[dfs][2-sat] JZOJ P3796 議案決定

 

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行,每行表示一個大臣的投票。

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。

題解

  • 就是一道2-SAT問題ios

  • 點u->v表明u發生則v必然發生spa

  • 每個條件能夠拆爲這樣的兩個條件code

  • 如1 Y 2 N  對應的是  1N->2N   2Y->1Yblog

  • 咱們把1Y  1N稱爲對立節點遊戲

  • 那麼咱們怎麼找到將它們連起來且沒有對立節點的路徑(就是能夠找到一條路徑,由於對立節點沒有邊相連)事件

  • 能夠用dfs解決。事務

  • 若是對某個事務同意就必須對該事務反對(記爲事件A),且對某個事務反對就必須對該事務同意(記爲事件B)ip

  • 則不可能知足全部條件字符串

  • 不然: 若事件A成立,則對該事務必須反對 get

  •            若事件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 }
相關文章
相關標籤/搜索