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
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
否则输出 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 }