Party

hdu3062:http://acm.hdu.edu.cn/showproblem.php?pid=3062

题意:中文题。

题解:很明显的2-sat。然后要深刻理解命题和逆否命题。如这一题,c1,c2,表示矛盾。则可以推出如果选c1,则要选~c2,逆否就是不选~c2就要选~c1,就是选c2和~c1,所以既可以加边了,然后就是2-sat。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<vector>
  6 using namespace std;
  7 const int N=20002;
  8 const int M=4000002;
  9 struct Node{
 10   int u;
 11   int v;
 12 }e[N*2];
 13 struct Edge{
 14     int to,next;
 15 } edge[M];
 16 
 17 int  n,m,cnt,dep,top,atype;
 18 int  dfn[N],low[N],vis[N],head[N],st[N],belong[N],in[N],out[N],sum[N];
 19 //sum[i]记录第i个连通图的点的个数,in[i],out[i],表示缩点之后点的入度和初度。
 20 void init(){
 21       cnt=dep=top=atype=0;
 22     memset(head,-1,sizeof(head));
 23     memset(dfn,0,sizeof(dfn));
 24     memset(low,0,sizeof(low));
 25     memset(vis,0,sizeof(vis));
 26     memset(belong,0,sizeof(belong));
 27     memset(in,0,sizeof(in));
 28     memset(out,0,sizeof(out));
 29     memset(sum,0,sizeof(sum));
 30 }
 31 void addedge(int u,int v){
 32     edge[cnt].to=v;
 33     edge[cnt].next=head[u];
 34     head[u]=cnt++;
 35 }
 36 
 37 void Tarjan(int u){
 38     dfn[u]=low[u]=++dep;
 39     st[top++]=u;
 40     vis[u]=1;
 41     for(int i=head[u]; i!=-1; i=edge[i].next){
 42         int v=edge[i].to;
 43         if(!dfn[v]){
 44             Tarjan(v);
 45             low[u]=min(low[u],low[v]);
 46         }
 47         else if(vis[v]){
 48             low[u]=min(low[u],dfn[v]);
 49         }
 50     }
 51     int j;
 52     if(dfn[u]==low[u]){
 53         atype++;
 54         do{
 55             j=st[--top];
 56             belong[j]=atype;
 57             sum[atype]++;   //记录每个连通分量中点的个数
 58             vis[j]=0;
 59         }
 60         while(u!=j);
 61     }
 62 }
 63 int main(){
 64    while(~scanf("%d%d",&n,&m)){
 65        init();
 66        for(int i=1;i<=m;i++){
 67          int a1,a2,c1,c2;a1++,a2++;
 68             scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
 69              a1++;a2++;
 70             if(c1==0&&c2==0){
 71                 addedge(a1,a2+n);
 72                 addedge(a2,a1+n);
 73             }
 74             if(c1==0&&c2==1){
 75                 addedge(a1,a2);
 76                 addedge(a2+n,a1+n);
 77             }
 78             if(c1==1&&c2==0){
 79                 addedge(a1+n,a2+n);
 80                 addedge(a2,a1);
 81             }
 82             if(c1==1&&c2==1){
 83                 addedge(a1+n,a2);
 84                 addedge(a2+n,a1);
 85             }
 86        }
 87        for(int i=1;i<=n*2;i++)
 88           if(!dfn[i])Tarjan(i);
 89          bool flag=false;
 90          for(int i=1;i<=n;i++){
 91             if(belong[i]==belong[i*2]){
 92                 flag=true;
 93             }
 94          }
 95          if(!flag){
 96             printf("YES\n");
 97          }
 98          else
 99            printf("NO\n");
100    }
101 }
View Code

 

posted on 2014-08-22 18:20  天依蓝  阅读(142)  评论(0编辑  收藏  举报

导航