1. 程式人生 > >BZOJ2199: [Usaco2011 Jan]奶牛議會

BZOJ2199: [Usaco2011 Jan]奶牛議會

while ostream i++ ins style () zoj none tar

m<=4000條關系描述n<=1000個事件,每條關系描述了一個或語句表示“x事件發生或不發生”或“y事件發生或不發生”,求每個事件是必發生、必不發生還是都行,無解輸出IMPOSSIBLE。

是一個2-SAT問題。建圖後把每個事件發生不發生都dfs一遍即可。聽說縮點後會更快,就寫了個tarjan。

技術分享
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<algorithm>
  4 #include<cstdlib>
  5 #include<math.h>
  6 //#include<iostream>
7 using namespace std; 8 9 int n,m; 10 #define maxn 2017 11 #define maxm 10011 12 struct Graph 13 { 14 struct Edge{int to,next;}edge[maxm]; 15 int first[maxn],le;int n; 16 Graph() {memset(first,0,sizeof(first));le=2;} 17 void in(int x,int y) 18 { 19 edge[le].to=y;
20 edge[le].next=first[x]; 21 first[x]=le++; 22 } 23 void addclause(int x,bool xval,int y,bool yval) 24 { 25 x=(x<<1)+xval; 26 y=(y<<1)+yval; 27 in(x^1,y); 28 in(y^1,x); 29 } 30 int Time,low[maxn],dfn[maxn],sta[maxn],top,bel[maxn],tot;bool
insta[maxn]; 31 void tarjan(int x) 32 { 33 low[x]=dfn[x]=++Time; 34 sta[++top]=x;insta[x]=1; 35 for (int i=first[x],to=edge[i].to;i;i=edge[i].next,to=edge[i].to) 36 { 37 if (!dfn[to]) tarjan(to),low[x]=min(low[x],low[to]); 38 else if (insta[to]) low[x]=min(low[x],dfn[to]); 39 } 40 if (dfn[x]==low[x]) 41 { 42 tot++; 43 while (sta[top]!=x) bel[sta[top]]=tot,insta[sta[top--]]=0; 44 bel[x]=tot,insta[sta[top--]]=0; 45 } 46 } 47 void tarjan() 48 { 49 memset(dfn,0,sizeof(dfn)); 50 Time=tot=top=0; 51 memset(insta,0,sizeof(insta)); 52 for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); 53 } 54 }g,tg; 55 bool ok() 56 { 57 for (int i=1;i<=n;i++) 58 if (g.bel[i<<1]==g.bel[(i<<1)^1]) return 0; 59 return 1; 60 } 61 void build() 62 { 63 tg.n=g.tot; 64 for (int i=1;i<=g.n;i++) 65 for (int j=g.first[i],to=g.edge[j].to;j;j=g.edge[j].next,to=g.edge[j].to) 66 if (g.bel[i]!=g.bel[to]) tg.in(g.bel[i],g.bel[to]); 67 } 68 int vis[maxn],Time=0; 69 void dfs(int x) 70 { 71 vis[x]=Time; 72 for (int i=tg.first[x];i;i=tg.edge[i].next) 73 if (vis[tg.edge[i].to]!=Time) dfs(tg.edge[i].to); 74 } 75 bool check(int x) 76 { 77 Time++;dfs(x); 78 for (int i=1;i<=n;i++) 79 if (vis[g.bel[i<<1]]==Time && vis[g.bel[i<<1]]==vis[g.bel[(i<<1)^1]]) return 0; 80 return 1; 81 } 82 char ans[maxn];int x,y;char c[5],d[5]; 83 int main() 84 { 85 scanf("%d%d",&n,&m); 86 g.n=(n<<1)^1; 87 for (int i=1;i<=m;i++) 88 { 89 scanf("%d%s%d%s",&x,c,&y,d); 90 g.addclause(x,c[0]==Y,y,d[0]==Y); 91 } 92 g.tarjan(); 93 if (!ok()) {puts("IMPOSSIBLE");return 0;} 94 build(); 95 for (int i=1;i<=n;i++) 96 { 97 bool x=check(g.bel[i<<1]),y=check(g.bel[(i<<1)^1]); 98 if (x) 99 { 100 if (y) ans[i]=?; 101 else ans[i]=N; 102 } 103 else 104 { 105 if (y) ans[i]=Y; 106 else {puts("IMPOSSIBLE");return 0;} 107 } 108 } 109 ans[n+1]=\0;puts(ans+1); 110 return 0; 111 }
View Code

BZOJ2199: [Usaco2011 Jan]奶牛議會