Description
Input
Output
Sample Input
1 2 0 1 2 0 1 1 2 2 4 0 1 2 3 4 5 0 3 0 4 1 3 1 4
Sample Output
yes no
2-sat最难的是如何建图加边 这里对一个队 a,b,c b和c是绑定的 那么我们就可以转换为熟悉的 2-sat
ACcode:
#include <map> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <stdlib.h> #include <iostream> #include <algorithm> #define maxn 100000 using namespace std; struct Node{ int to,next; }edge[maxn]; int head[maxn],tot; void init(){tot=0;memset(head,-1,sizeof(head));} void add(int u,int v){edge[tot].to=v;edge[tot].next=head[u];head[u]=tot++;} int low[maxn],dfn[maxn],Stack[maxn],Belong[maxn]; int Index,top; int scc; bool Instack[maxn]; int num[maxn]; void tarjan(int u){ int v; low[u]=dfn[u]=++Index; Stack[top++]=u; Instack[u]=true; for(int i=head[u];i!=-1;i=edge[i].next){ v=edge[i].to; if(!dfn[v]){ tarjan(v); low[u]=min(low[u],low[v]); } else if(Instack[v]&&low[u]>dfn[v]) low[u]=dfn[v]; } if(low[u]==dfn[u]){ scc++; do{ v=Stack[--top]; Instack[v]=false; Belong[v]=scc; num[scc]++; } while(v!=u); } } void solve(int n){ memset(dfn,0,sizeof(dfn)); memset(Instack,false,sizeof(Instack)); Index=scc=top=0; for(int i=0;i<n;++i)if(!dfn[i])tarjan(i); for(int i=0;i<n;i+=2) if(Belong[i]==Belong[i+1]){ printf("no\n");return; } printf("yes\n"); } int aa[maxn]; int main(){ int t,m,n,a,b,c,x,y; while(~scanf("%d%d",&t,&m)){ init();n=t*2; for(int i=0;i<t;++i){ scanf("%d%d%d",&a,&b,&c); aa[a]=2*i;aa[b]=aa[c]=2*i+1; } for(int i=0;i<m;++i){ scanf("%d%d",&x,&y); add(aa[x],aa[y]^1); add(aa[y],aa[x]^1); } solve(n); } return 0; }