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 "); 74 else printf("NO "); 75 } 76 }