hdu 4115

新手学习2-sat算法,看了一个多小时,才看懂。然后类比着打代码,结果出来和网上的一样。。。不过这一题可以作为有向图缩点的模板,同时也可以比较清晰的理解2-sat的内涵,所以在这里仍然贴出来。
View Code
  1 #include<iostream>
2 #include<vector>
3 #include<cstring>
4 #include<cstdio>
5 #include<algorithm>
6 using namespace std;
7 const int maxn=20001;
8 vector<int>edge[maxn];
9 int st[maxn];
10 int dfn[maxn],low[maxn];
11 int top,btype,tdfn;
12 int belong[maxn];
13 bool ins[maxn];
14 int bob,alice[maxn];
15 void dfs(int s)
16 {
17 int t;
18 dfn[s]=low[s]=++tdfn;
19 ins[s]=1;
20 st[++top]=s;
21 for(int i=0;i<edge[s].size();i++)
22 {
23 int t=edge[s][i];
24 if(!dfn[t])
25 {
26 dfs(t);
27 if(low[t]<low[s])
28 low[s]=low[t];
29 }
30 else if(ins[t]&&dfn[t]<low[s])
31 low[s]=dfn[t];
32 }
33 if(dfn[s]==low[s])
34 {
35 btype++;
36 do
37 {
38 t=st[top--];
39 ins[t]=0;
40 belong[t]=btype;
41 }while(t!=s);
42 }
43 }
44 void scc(int n)
45 {
46 top=btype=tdfn=0;
47 memset(ins,0,sizeof(ins));
48 memset(dfn,0,sizeof(dfn));
49 for(int i=1;i<=n;i++)
50 if(!dfn[i])
51 dfs(i);
52 }
53 int main()
54 {
55 int t;int n,m,a,b,k;
56 int cases=1;
57 scanf("%d",&t);
58 while(t--)
59 {
60 scanf("%d%d",&n,&m);
61 for(int i=0;i<=2*n;i++)
62 edge[i].clear();
63 for(int i=1;i<=n;i++)
64 {
65 scanf("%d",&bob);
66 if(bob==1)
67 {
68 alice[i]=1;
69 alice[i+n]=2;
70 }
71 else if(bob==2)
72 {
73 alice[i]=2;
74 alice[i+n]=3;
75 }
76 else if(bob==3)
77 {
78 alice[i]=3;
79 alice[i+n]=1;
80 }
81 }
82 for(int i=0;i<m;i++)
83 {
84 scanf("%d%d%d",&a,&b,&k);
85 if(k==1)
86 {
87 if(alice[a]==alice[b])
88 {
89 edge[a].push_back(b+n);
90 edge[b].push_back(a+n);
91 }
92 if(alice[a]==alice[b+n])
93 {
94 edge[a].push_back(b);
95 edge[b+n].push_back(a+n);
96 }
97 if(alice[a+n]==alice[b])
98 {
99 edge[a+n].push_back(b+n);
100 edge[b].push_back(a);
101 }
102 if(alice[a+n]==alice[b+n])
103 {
104 edge[a+n].push_back(b);
105 edge[b+n].push_back(a);
106 }
107 }
108 if(k==0)
109 {
110 if(alice[a]!=alice[b])
111 {
112 edge[a].push_back(b+n);
113 edge[b].push_back(a+n);
114 }
115 if(alice[a]!=alice[b+n])
116 {
117 edge[a].push_back(b);
118 edge[b+n].push_back(a+n);
119 }
120 if(alice[a+n]!=alice[b])
121 {
122 edge[a+n].push_back(b+n);
123 edge[b].push_back(a);
124 }
125 if(alice[a+n]!=alice[b+n])
126 {
127 edge[a+n].push_back(b);
128 edge[b+n].push_back(a);
129 }
130 }
131 }
132 scc(2*n);
133 int flag=1;
134 for(int i=1;i<=n;i++)
135 {
136 if(belong[i]==belong[i+n])
137 {
138 flag=0;
139 break;
140 }
141 }
142 if(flag) printf("Case #%d: yes\n",cases++);
143 else printf("Case #%d: no\n",cases++);
144 }
145 return 0;
146 }
posted @ 2012-03-17 15:48  静静的等待_93  阅读(418)  评论(0编辑  收藏  举报