hdu1824-Let's go home:图论2-SAT

 

关键在于找出一定矛盾的条件,设一队的3个人为(a,b,c),a为队长,那么(a不留下,b不留下)矛盾,(a不留下,c不留下)矛盾; 对于每一对队员,(a留下,b留下)矛盾。

把模型建好,剩下的就是套模板了。


 

 1 #include<cstdio>
 2 #include<vector>
 3 #include<cstring>
 4 using namespace std;
 5 
 6 const int maxn = 3000+10;
 7 
 8 struct TwoSAT
 9 {
10     int n;
11     vector<int> G[maxn*2];
12     bool mark[maxn*2];
13     int S[maxn*2], c;
14 
15     bool dfs(int x)
16     {
17         if (mark[x^1]) return false;
18         if (mark[x]) return true;
19         mark[x] = true;
20         S[c++] = x;
21         for (int i = 0; i < G[x].size(); i++)
22             if (!dfs(G[x][i])) return false;
23         return true;
24     }
25 
26     void init(int n)
27     {
28         this->n = n;
29         for (int i = 0; i < n*2; i++) G[i].clear();
30         memset(mark, 0, sizeof(mark));
31     }
32 
33     // x = xval or y = yval
34     void add_clause(int x, int xval, int y, int yval)
35     {
36         x = x * 2 + xval;
37         y = y * 2 + yval;
38         G[x^1].push_back(y);
39         G[y^1].push_back(x);
40     }
41 
42     bool solve()
43     {
44         for(int i = 0; i < n*2; i += 2)
45             if(!mark[i] && !mark[i+1])
46             {
47                 c = 0;
48                 if(!dfs(i))
49                 {
50                     while(c > 0) mark[S[--c]] = false;
51                     if(!dfs(i+1)) return false;
52                 }
53             }
54         return true;
55     }
56 };
57 
58 
59 ///////////////////////////////////////////////////////////////
60 #include <iostream>
61 #include <cmath>
62 using namespace std;
63 TwoSAT solver;
64 
65 int main()
66 {
67     int t,m;
68     while(~scanf("%d%d",&t,&m))
69     {
70         solver.init(t*3);
71         for(int i=0;i<t;i++)
72         {
73             int a,b,c;
74             scanf("%d%d%d",&a,&b,&c);
75             solver.add_clause(a,0,b,0); // 0表示不留下,1表示留下
76             solver.add_clause(a,0,c,0);
77             //solver.add_clause(b,1,c,0);
78             //solver.add_clause(c,1,b,0);
79         }
80 
81         for(int i=0;i<m;i++)
82         {
83             int a,b;
84             scanf("%d %d",&a,&b);
85             solver.add_clause(a,1,b,1);
86         }
87         printf("%s\n",solver.solve()?"yes":"no");
88     }
89     return 0;
90 }

 

posted @ 2014-10-06 01:39  PlasticSpirit  阅读(296)  评论(0编辑  收藏  举报