关键在于找出一定矛盾的条件,设一队的3个人为(a,b,c),a为队长,那么(a不留下,b不留下)矛盾,(a不留下,c不留下)矛盾; 对于每一对队员,(a留下,b留下)矛盾。
把模型建好,剩下的就是套模板了。
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std; const int maxn = +; struct TwoSAT
{
int n;
vector<int> G[maxn*];
bool mark[maxn*];
int S[maxn*], c; bool dfs(int x)
{
if (mark[x^]) return false;
if (mark[x]) return true;
mark[x] = true;
S[c++] = x;
for (int i = ; i < G[x].size(); i++)
if (!dfs(G[x][i])) return false;
return true;
} void init(int n)
{
this->n = n;
for (int i = ; i < n*; i++) G[i].clear();
memset(mark, , sizeof(mark));
} // x = xval or y = yval
void add_clause(int x, int xval, int y, int yval)
{
x = x * + xval;
y = y * + yval;
G[x^].push_back(y);
G[y^].push_back(x);
} bool solve()
{
for(int i = ; i < n*; i += )
if(!mark[i] && !mark[i+])
{
c = ;
if(!dfs(i))
{
while(c > ) mark[S[--c]] = false;
if(!dfs(i+)) return false;
}
}
return true;
}
}; ///////////////////////////////////////////////////////////////
#include <iostream>
#include <cmath>
using namespace std;
TwoSAT solver; int main()
{
int t,m;
while(~scanf("%d%d",&t,&m))
{
solver.init(t*);
for(int i=;i<t;i++)
{
int a,b,c;
scanf("%d%d%d",&a,&b,&c);
solver.add_clause(a,,b,); // 0表示不留下,1表示留下
solver.add_clause(a,,c,);
//solver.add_clause(b,1,c,0);
//solver.add_clause(c,1,b,0);
} for(int i=;i<m;i++)
{
int a,b;
scanf("%d %d",&a,&b);
solver.add_clause(a,,b,);
}
printf("%s\n",solver.solve()?"yes":"no");
}
return ;
}