POJ3648 Wedding
2-sat
建图就可以把男女对立看为2-sat的初始状态,i为男的和新娘在一排,i+n为男的和新娘在对立排。只关心是不是都在新郎这一边就可以了。
由于一开始新郎和新娘对立所以连一条0到0+n的边
改了一上午,最后发现s没清空つ﹏⊂
By:大奕哥
1 #include<iostream> 2 #include<cstdlib> 3 #include<cstdio> 4 #include<algorithm> 5 #include<cstring> 6 #include<vector> 7 #include<queue> 8 using namespace std; 9 const int N=5e4+10; 10 struct edge{int to,nex;}e[5000005],d[5000005]; 11 int head[N],dead[N],low[N],dfn[N],vis[N],col[N],opp[N],ans[N],in[N],s[N]; 12 int n,m,cnt,ecnt,top,num,dcnt; 13 queue<int>q; 14 void add(int x,int y) 15 { 16 e[++ecnt].to=y;e[ecnt].nex=head[x];head[x]=ecnt; 17 } 18 void add1(int x,int y) 19 { 20 d[++dcnt].to=y;d[dcnt].nex=dead[x];dead[x]=dcnt; 21 } 22 void dfs(int x) 23 { 24 vis[x]=1;s[++top]=x; 25 low[x]=dfn[x]=++cnt; 26 for(int i=head[x];i;i=e[i].nex) 27 { 28 int y=e[i].to; 29 if(!dfn[y]) 30 { 31 dfs(y); 32 low[x]=min(low[x],low[y]); 33 } 34 else if(vis[y])low[x]=min(low[x],dfn[y]); 35 } 36 if(low[x]==dfn[x]) 37 { 38 num++; 39 while(s[top+1]!=x) 40 { 41 int a=s[top--]; 42 vis[a]=0; 43 col[a]=num; 44 } 45 } 46 return; 47 } 48 void init() 49 { 50 top=ecnt=cnt=num=dcnt=0; 51 memset(s,0,sizeof(s)); 52 memset(head,0,sizeof(head)); 53 memset(dead,0,sizeof(dead)); 54 memset(low,0,sizeof(low)); 55 memset(dfn,0,sizeof(dfn)); 56 memset(in,0,sizeof(in)); 57 memset(col,0,sizeof(col)); 58 memset(ans,-1,sizeof(ans)); 59 memset(opp,0,sizeof(opp)); 60 memset(vis,0,sizeof(vis)); 61 } 62 void toposort() 63 { 64 for(int x=0;x<n*2;++x) 65 { 66 for(int i=head[x];i;i=e[i].nex) 67 { 68 int y=e[i].to; 69 if(col[x]==col[y])continue; 70 add1(col[y],col[x]); 71 in[col[x]]++; 72 } 73 } 74 for(int i=1;i<=num;++i) 75 { 76 if(!in[i])q.push(i); 77 } 78 while(!q.empty()) 79 { 80 int x=q.front();q.pop(); 81 if(ans[x]==-1){ 82 ans[x]=1;ans[opp[x]]=0; 83 } 84 for(int i=dead[x];i;i=d[i].nex) 85 { 86 int y=d[i].to; 87 in[y]--; 88 if(!in[y])q.push(y); 89 } 90 } 91 return; 92 } 93 bool solve() 94 { 95 for(int i=0;i<2*n;++i) 96 if(!dfn[i])dfs(i); 97 for(int i=0;i<n;++i) 98 { 99 100 if(col[i]==col[i+n]){ 101 return 0; 102 } 103 opp[col[i]]=col[i+n]; 104 opp[col[i+n]]=col[i]; 105 } 106 return 1; 107 } 108 int main() 109 { 110 //freopen("1.out","r",stdin); 111 //freopen("my.out","w",stdout); 112 while(~scanf("%d%d",&n,&m)) 113 { 114 if(!n&&!m)return 0; 115 init(); 116 int x=0,y=0,a1=0,b1=0,a2=0,b2=0; 117 char c1,c2; 118 for(int i=1;i<=m;++i) 119 { 120 scanf("%d%c %d%c",&x,&c1,&y,&c2); 121 if(c1=='h')a1=x+n,a2=x; 122 else a1=x,a2=x+n; 123 if(c2=='h')b1=y+n,b2=y; 124 else b1=y,b2=y+n; 125 add(a1,b2);add(b1,a2); 126 }
126 for(int i=0;i<n;++i) 127 add(i,i+n); 128 if(solve()) 129 { 130 toposort(); 131 for(int i=1;i<n;++i) 132 { 133 if(ans[col[i]]==1)printf("%dh ",i); 134 else printf("%dw ",i); 135 } 136 printf("\n"); 137 } 138 else 139 puts("bad luck"); 140 } 141 return 0; 142 }
生命中真正重要的不是你遭遇了什么,而是你记住了哪些事,又是如何铭记的。