2-SAT,根据题意建好图,求一下强联通分量,判断一下就可以了
#include<cstdio> #include<cstring> #include<cmath> #include<vector> #include<stack> #include<algorithm> using namespace std; const int maxn=6005; int T,M; vector<int>G[maxn]; vector<int>FG[maxn]; int Belong[maxn],flag[maxn]; stack<int>S; int Block; void init() { if(!S.empty()) S.pop(); for(int i=0; i<maxn; i++) G[i].clear(); for(int i=0; i<maxn; i++) FG[i].clear(); memset(Belong,0,sizeof Belong); memset(flag,0,sizeof flag); Block=0; } void dfs1(int now) { flag[now]=1; for(int i=0; i<G[now].size(); i++) if(!flag[G[now][i]]) dfs1(G[now][i]); S.push(now); } void dfs2(int now) { Belong[now]=Block; for(int i=0; i<FG[now].size(); i++) if(!Belong[FG[now][i]]) dfs2(FG[now][i]); } void Add(int x,int y) { G[x].push_back(y); FG[y].push_back(x); } int main() { while(~scanf("%d%d",&T,&M)) { init(); for(int i=0; i<T; i++) { int a,b,c; scanf("%d%d%d",&a,&b,&c); Add(3*T+a,b); Add(3*T+a,c); Add(3*T+b,a); Add(3*T+c,a); } for(int i=0; i<M; i++) { int a,b; scanf("%d%d",&a,&b); Add(a,3*T+b); Add(b,3*T+a); } for(int i=0; i<6*T; i++) if(!flag[i]) dfs1(i); while(!S.empty()) { int Top=S.top(); S.pop(); if(!Belong[Top]) { Block++; dfs2(Top); } } int ans=1; for(int i=0; i<3*T; i++) { if(Belong[i]==Belong[3*T+i]) { ans=0; break; } } if(ans==1) printf("yes "); else printf("no "); } return 0; }