昨天刚开始看2-sat, 强连通分量的更深层次的应用。。
目前为止还只能判断一个2-sat是否有解,还不能求出具体的解,对于后面的拓扑排序理解的不是很透彻。。
2 1 0 1 1 1强连通之后加一个判断,判断每一对夫妻会不会同在一个强连通分量里面,如果是则该2-sat无解,输出NO,else 输出YES。。代码:View Code1 # include < stdio.h >
2 # define N 2005
3 # define M 2000005
4 struct node{
5 int from,to,next;
6 }edge1[M],edge2[M];
7 int head1[N],head2[N],visit1[N],Belong[N],T[N],visit2[N];
8 int Tcnt,Bcnt,tol1,tol2;
9 void add( int a, int b)
10 {
11 edge1[tol1].from = a;edge1[tol1].to = b;edge1[tol1].next = head1[a];head1[a] = tol1 ++ ;
12 edge2[tol2].from = b;edge2[tol2].to = a;edge2[tol2].next = head2[b];head2[b] = tol2 ++ ;
13 }
14 void dfs1( int x)
15 {
16 int j;
17 visit1[x] = 1 ;
18 for (j = head1[x];j !=- 1 ;j = edge1[j].next)
19 {
20 if (visit1[edge1[j].to] == 0 ) dfs1(edge1[j].to);
21 }
22 T[Tcnt ++ ] = x;
23 }
24 void dfs2( int x)
25 {
26 int j;
27 visit2[x] = 1 ;
28 Belong[x] = Bcnt;
29 for (j = head2[x];j !=- 1 ;j = edge2[j].next)
30 {
31 if (visit2[edge2[j].to] == 0 ) dfs2(edge2[j].to);
32 }
33 }
34 int main()
35 {
36 int i,n,m,a,b,c1,c2;
37 while (scanf( " %d%d " , & n, & m) != EOF)
38 {
39 for (i = 0 ;i <= 2 * n;i ++ )
40 {
41 head1[i] =- 1 ;
42 head2[i] =- 1 ;
43 visit1[i] = 0 ;
44 visit2[i] = 0 ;
45 }
46 Bcnt = Tcnt = 0 ;
47 tol1 = 0 ;
48 tol2 = 0 ;
49 for (i = 1 ;i <= m;i ++ )
50 {
51 scanf( " %d%d%d%d " , & a, & b, & c1, & c2);
52 a ++ ;
53 b ++ ;
54 a *= 2 ;
55 b *= 2 ;
56 if (c1 == 0 && c2 == 0 )
57 {
58 add(a - 1 ,b);
59 add(b - 1 ,a);
60 }
61 else if (c1 == 0 && c2 == 1 )
62 {
63 add(a - 1 ,b - 1 );
64 add(b,a);
65 }
66 else if (c1 == 1 && c2 == 0 )
67 {
68 add(a,b);
69 add(b - 1 ,a - 1 );
70 }
71 else
72 {
73 add(a,b - 1 );
74 add(b,a - 1 );
75 }
76 }
77 for (i = 1 ;i <= 2 * n;i ++ )
78 if (visit1[i] == 0 ) dfs1(i);
79 for (i = Tcnt - 1 ;i >= 0 ;i -- )
80 {
81 if (visit2[T[i]] == 0 )
82 {
83 dfs2(T[i]);
84 Bcnt ++ ;
85 }
86 }
87 for (i = 1 ;i <= 2 * n - 1 ;i += 2 )
88 {
89 if (Belong[i] == Belong[i + 1 ]) break ;
90 }
91 if (i <= 2 * n - 1 ) printf( " NO\n " );
92 else printf( " YES\n " );
93 }
94 return 0 ;
95 }