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 }

 

转载于:https://www.cnblogs.com/nbwzyzngyl/p/8309249.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值