hdu4115:Eliminate the Conflict

n<=10000局剪刀石头布,对面第i局出Ai,m<=10000种对你出什么提出的要求:Xi Yi Wi 表示第Xi局和第Yi局,Wi=1:必须不同;Wi=0:必须相同,问是否存在你一局都不能输的可行解。

一开始对面就把你每局的选择减成2个了,又是一个2-SAT问题。至于建图一定要考虑周全!注意一个条件对Xi和Yi带来的影响都要考虑!

A和B必须不同:

A和B必须相同:错误!未考虑清楚“必须相同”的含义,就是说,如果B没有一样的,那么A这个就不能选!

那么还要把这些不能选的点删掉吗?看了大神博客,发现神奇姿势:这样A1和B3就永远不可能选了,因为一旦选立刻出现矛盾。

注意事项:由于建边过程繁琐,中途思路混乱WA了一次。注意检查!!!

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<cmath>
  6 //#include<iostream>
  7 using namespace std;
  8 
  9 int n,m,T;
 10 #define maxn 10011*2
 11 #define maxe 10011*4
 12 struct Edge{int to,next;};
 13 struct Graph
 14 {
 15     Edge edge[maxe];int le;
 16     int first[maxn],vis[maxn];
 17     void clear()
 18     {
 19         le=2;
 20         memset(first,0,sizeof(first));
 21     }
 22     void insert(int x,int y)
 23     {
 24         edge[le].to=y;
 25         edge[le].next=first[x];
 26         first[x]=le++;
 27     }
 28     int sta[maxn],top;
 29     bool dfs(int x)
 30     {
 31         if (vis[x^1]) return 0;
 32         if (vis[x]) return 1;
 33         vis[x]=1;
 34         sta[++top]=x;
 35         for (int i=first[x];i;i=edge[i].next)
 36             if (!dfs(edge[i].to)) return 0;
 37         return 1;
 38     }
 39     bool twosat()
 40     {
 41         memset(vis,0,sizeof(vis));
 42         for (int i=1;i<=n;i++)
 43             if (!vis[i*2] && !vis[i*2+1])
 44             {
 45                 top=0;
 46                 if (!dfs(i*2))
 47                 {
 48                     for (;top;top--) vis[sta[top]]=0;
 49                     if (!dfs(i*2+1)) return 0;
 50                 }
 51             }
 52         return 1;
 53     }
 54 }G;
 55 struct Point
 56 {
 57     int a,b;
 58 }game[maxn];
 59 int x,y,w;
 60 int main()
 61 {
 62     scanf("%d",&T);
 63     for (int t=1;t<=T;t++)
 64     {
 65         scanf("%d%d",&n,&m);
 66         for (int i=1;i<=n;i++)
 67         {
 68             scanf("%d",&x);
 69             if (x==1) {game[i].a=1;game[i].b=2;}
 70             if (x==2) {game[i].a=2;game[i].b=3;}
 71             if (x==3) {game[i].a=1;game[i].b=3;}
 72         }
 73         G.clear();
 74         for (int i=1;i<=m;i++)
 75         {
 76             scanf("%d%d%d",&x,&y,&w);
 77             if (w)
 78             {
 79                 if (game[x].a==game[y].a)
 80                 {
 81                     G.insert(x*2,y*2+1);
 82                     G.insert(y*2,x*2+1);
 83                 }
 84                 if (game[x].a==game[y].b)
 85                 {
 86                     G.insert(x*2,y*2);
 87                     G.insert(y*2+1,x*2+1);
 88                 }
 89                 if (game[x].b==game[y].a)
 90                 {
 91                     G.insert(x*2+1,y*2+1);
 92                     G.insert(y*2,x*2);
 93                 }
 94                 if (game[x].b==game[y].b)
 95                 {
 96                     G.insert(x*2+1,y*2);
 97                     G.insert(y*2+1,x*2);
 98                 }
 99             }
100             else
101             {
102                 if (game[x].a==game[y].a)
103                 {
104                     G.insert(x*2,y*2);
105                     G.insert(y*2,x*2);
106                 }
107                 else if (game[x].a==game[y].b)
108                 {
109                     G.insert(x*2,y*2+1);
110                     G.insert(y*2+1,x*2);
111                 }
112                 else G.insert(x*2,x*2+1);
113                 if (game[x].b==game[y].a)
114                 {
115                     G.insert(x*2+1,y*2);
116                     G.insert(y*2,x*2+1);
117                 }
118                 else if (game[x].b==game[y].b)
119                 {
120                     G.insert(x*2+1,y*2+1);
121                     G.insert(y*2+1,x*2+1);
122                 }
123                 else G.insert(x*2+1,x*2);
124                 if (game[y].a!=game[x].a && game[y].a!=game[x].b)
125                     G.insert(y*2,y*2+1);
126                 if (game[y].b!=game[x].a && game[y].b!=game[x].b)
127                     G.insert(y*2+1,y*2);
128             }
129         }
130         printf("Case #%d: ",t);
131         if (G.twosat()) printf("yes");else printf("no");
132         puts("");
133     }
134     return 0;
135 }
View Code

 

posted @ 2017-07-20 16:48  Blue233333  阅读(193)  评论(0编辑  收藏  举报