昨天刚开始看2-sat, 强连通分量的更深层次的应用。。 

目前为止还只能判断一个2-sat是否有解,还不能求出具体的解,对于后面的拓扑排序理解的不是很透彻。。

Problem Description
有n对夫妻被邀请参加一个聚会,因为场地的问题,每对夫妻中只有1人可以列席。在2n 个人中,某些人之间有着很大的矛盾(当然夫妻之间是没有矛盾的),有矛盾的2个人是不会同时出现在聚会上的。有没有可能会有n 个人同时列席?
 

Input
n: 表示有n对夫妻被邀请 (n<= 1000)
m: 表示有m 对矛盾关系 ( m < (n - 1) * (n -1))

在接下来的m行中,每行会有4个数字,分别是 A1,A2,C1,C2
A1,A2分别表示是夫妻的编号
C1,C2 表示是妻子还是丈夫 ,0表示妻子 ,1是丈夫
夫妻编号从 0 到 n -1
 

Output
如果存在一种情况 则输出YES
否则输出 NO
 

Sample Input
2 1 0 1 1 1
 
强连通之后加一个判断,判断每一对夫妻会不会同在一个强连通分量里面,如果是则该2-sat无解,输出NO,else 输出YES。。
代码:
View Code
1 # 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 }
posted on 2011-05-18 19:33  奋斗青春  阅读(604)  评论(0编辑  收藏  举报