Description
小C在玩一个游戏,在游戏中他扮演国王的角色。国王手下有M个大臣,他们有一天对国王要处理的N件事务进行投票。每个大臣可以对两件事务进行投票(赞成或反对),格式如下:x c_x y c_y(x, y为整数,c_x, c_y为“Y”(表示赞成)或“N”(表示反对)(不含双引号),表示这个大臣对事务x的态度为c_x,对事务y的态度为c_y)。这些大臣非常难以对付,如果国王的决定和某个大臣的两个意见都不同,那么这个大臣就会离开国王。小C认为不能让任何一个大臣离开国王,否则国王就无法正常地处理自己的事务。请你帮助小C做个决定。
Input
第一行,两个整数N, M。
接下来的M行,每行表示一个大臣的投票。
接下来的M行,每行表示一个大臣的投票。
Output
如果小C无论如何都只能让至少一个大臣离开国王,则输出“IMPOSSIBLE”(不含双引号),否则输出一个长度为N的字符串,如果第i件事务必须赞成,则第i个字符为“Y”;如果第i件事务必须反对,则第i个字符为“N”,否则第i个字符为“?”。
Sample Input
3 4
1 Y 2 N
1 N 2 N
1 Y 3 Y
1 Y 2 Y
Sample Output
YN?
Data Constraint
对于50%的数据,1<=N<=10,1<=M<=40;
对于全部的数据,1<=N<=1000,1<=M<=4000。
对于全部的数据,1<=N<=1000,1<=M<=4000。
题解
-
就是一道2-SAT问题
-
点u->v代表u发生则v必然发生
-
每一个条件可以拆为这样的两个条件
-
如1 Y 2 N 对应的是 1N->2N 2Y->1Y
-
我们把1Y 1N称为对立节点
-
那么我们怎么找到将它们连起来且没有对立节点的路径(就是可以找到一条路径,因为对立节点没有边相连)
-
可以用dfs解决。
-
如果对某个事务赞成就必须对该事务反对(记为事件A),且对某个事务反对就必须对该事务赞成(记为事件B)
-
则不可能满足所有条件
-
否则: 若事件A成立,则对该事务必须反对
-
若事件B成立,则对该事务必须赞成
代码
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<memory.h> 5 using namespace std; 6 int next[16011],last[16011],head[16011]; 7 int f[16011],k[16022][3],n,m,x,z,num,tot; 8 bool flag,must[16011][3]; 9 void insert(int x,int y) 10 { 11 next[++tot]=head[x]; 12 head[x]=tot; 13 last[tot]=y; 14 } 15 void dfs(int x) 16 { 17 if (flag==false) return; 18 f[x]=num; 19 if (f[x]==num&&f[x^1]==num) flag=false; 20 if (flag==false) return; 21 int i=head[x],j; 22 while (i!=0) 23 { 24 j=last[i]; 25 if (f[j]!=num) dfs(j); 26 i=next[i]; 27 } 28 29 } 30 int main() 31 { 32 scanf("%d%d",&n,&m); 33 char ch; 34 memset(must,true,sizeof(must)); 35 for (int i=1;i<=m;i++) 36 { 37 scanf("%d",&x); 38 while(ch=getchar(),ch!='Y'&&ch!='N'); 39 if (ch=='Y') z=1; else z=0; 40 if (z==1) k[i][1]=x*2+1; else k[i][1]=x*2; 41 scanf("%d",&x); 42 while(ch=getchar(),ch!='Y'&&ch!='N'); 43 if (ch=='Y') z=1; else z=0; 44 if (z==1) k[i][2]=x*2+1; else k[i][2]=x*2; 45 insert(k[i][2]^1,k[i][1]); 46 insert(k[i][1]^1,k[i][2]); 47 } 48 for (int i=1;i<=n;i++) 49 { 50 flag=true; 51 num++; 52 f[2*i]=num; 53 dfs(2*i); 54 if (flag==false) must[i][2]=false; 55 flag=true; 56 num++; 57 f[2*i+1]=num; 58 dfs(2*i+1); 59 if (flag==false) must[i][1]=false; 60 } 61 flag=true; 62 for (int i=1;i<=n;i++) if (must[i][1]==false&&must[i][2]==false) flag=false; 63 if (flag==false) printf("IMPOSSIBLE\n"); 64 else 65 for (int i=1;i<=n;i++) 66 { 67 if (must[i][2]==true&&must[i][1]==true) printf("?"); 68 if (must[i][2]==false&&must[i][1]==true) printf("Y"); 69 if (must[i][2]==true&&must[i][1]==false) printf("N"); 70 } 71 return 0; 72 }