hdu3062 Party(2-sat)

做~自己de王妃 提交于 2019-12-01 13:11:47

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 9751    Accepted Submission(s): 3056


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
 

 

Sample Output
YES
 
 
坑点:
数据是多组输入的
 
思路:
将一个点拆分成两个点,i*2为妻子,i*2+1为丈夫
假设a为妻子,a'为丈夫,b和b'意义相同
满足关系a与b矛盾的时候连接a->b',b->a',最后用tarjan缩点(染色),只要同一对夫妻不在一个联通分量里就有解,否则无解
 
 1 #include <cstdio>
 2 #include <vector>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 
 7 const int N=2e3+5;
 8 int low[N],dfn[N],Stack[N],belong[N];
 9 bool inStack[N];
10 int n,m,tot,tag,top;
11 vector<int> G[N];
12 
13 void init(){
14     top=tag=0;
15     memset(low,0,sizeof low);
16     memset(dfn,0,sizeof dfn);
17     memset(Stack,0,sizeof Stack);
18     memset(belong,0,sizeof belong);
19     memset(inStack,false,sizeof inStack);
20     for(int i=0;i<N;i++){
21         G[i].clear();
22     }
23 }
24 
25 void tarjan(int u){
26     int v;
27     low[u]=dfn[u]=++tot;
28     Stack[++top]=u;
29     inStack[u]=true;
30     for(int i=0;i<G[u].size();i++){
31         v=G[u][i];
32         if(dfn[v]==0){
33             tarjan(v);
34             low[u]=min(low[u],low[v]);
35         }
36         else if(inStack[v]==true){
37             low[u]=min(low[u],dfn[v]);
38         }
39     }
40     if(dfn[u]==low[u]){
41         tag++;
42         do{
43             v=Stack[top--];
44             inStack[v]=false;
45             belong[v]=tag;
46         }while(u!=v);
47     }
48 }
49 
50 int main(){
51     int a1,a2,c1,c2;
52     while(~scanf("%d",&n)){
53         scanf("%d",&m);
54         init();
55         for(int i=0;i<m;i++){
56             scanf("%d%d%d%d",&a1,&a2,&c1,&c2);
57             G[a1*2+c1].push_back(a2*2+(1-c2));
58             G[a2*2+c2].push_back(a1*2+(1-c1));
59         }
60         for(int i=0;i<2*n;i++){
61             if(dfn[i]==0){
62                 tot=0;
63                 tarjan(i);
64             }
65         }
66         int flag=1;
67         for(int i=0;i<n;i++){
68             if(belong[i*2]==belong[i*2+1]){
69                 flag=0;
70                 break;
71             }
72         }
73         if(flag==1)printf("YES\n");
74         else printf("NO\n");
75     }
76 }

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!