poj 3648 Wedding【2-SAT+tarjan+拓撲】
阿新 • • 發佈:2018-11-18
看錯題*n,注意是輸出新娘這邊的……
按2-SAT規則連互斥的邊,然後注意連一條(1,1+n)表示新娘必選
然後輸出color[belong[i]]==color[belong[1+n(新娘)]]的點即可
#include<iostream> #include<cstdio> #include<cstring> #include<vector> #include<queue> using namespace std; const int N=1000005; int n,m,h[N],cnt,dfn[N],low[N],tot,s[N],top,bl[N],col,id[N],c[N],d[N],du[N]; bool v[N]; struct qwe { int ne,no,to; }e[N<<1]; int read() { int r=0,f=1; char p=getchar(); while(p>'9'||p<'0') { if(p=='-') f=-1; p=getchar(); } while(p>='0'&&p<='9') { r=r*10+p-48; p=getchar(); } if(p=='w') r+=n; return r; } void add(int u,int v) {//cerr<<u<<" "<<v<<endl; cnt++; e[cnt].ne=h[u]; e[cnt].no=u; e[cnt].to=v; h[u]=cnt; } void tarjan(int u) { dfn[u]=low[u]=++tot; v[s[++top]=u]=1; for(int i=h[u];i;i=e[i].ne) { if(!dfn[e[i].to]) { tarjan(e[i].to); low[u]=min(low[u],low[e[i].to]); } else if(v[e[i].to]) low[u]=min(low[u],dfn[e[i].to]); } if(low[u]==dfn[u]) { col++; while(s[top]!=u) { bl[s[top]]=col; v[s[top--]]=0; } bl[s[top]]=col; v[s[top--]]=0; } } int main() { while(1) { n=read(),m=read(); if(n+m==0) break; memset(dfn,0,sizeof(dfn)); memset(h,0,sizeof(h)); memset(c,0,sizeof(c)); memset(v,0,sizeof(v)); memset(du,0,sizeof(du)); cnt=0,tot=0,top=0,col=0; for(int i=1;i<=n;i++) d[i]=i+n,d[i+n]=i; for(int i=1;i<=m;i++) { int x=read()+1,y=read()+1; add(x,d[y]),add(y,d[x]); } add(1+n,1); for(int i=1;i<=n+n;i++) if(!dfn[i]) tarjan(i); bool fl=0; for(int i=1;i<=n;i++) { if(bl[i]==bl[i+n]) { fl=1; break; } id[bl[i]]=bl[i+n]; id[bl[i+n]]=bl[i]; } if(fl) { puts("bad luck"); continue; } vector<pair<int,int> >b; for(int i=1;i<=cnt;i++) if(bl[e[i].no]!=bl[e[i].to]) b.push_back(make_pair(bl[e[i].to],bl[e[i].no])); memset(h,0,sizeof(h)); cnt=0; for(int i=0,len=b.size();i<len;i++) add(b[i].first,b[i].second),du[b[i].second]++; queue<int>q; for(int i=1;i<=col;i++) if(!du[i]) q.push(i); while(!q.empty()) { int u=q.front();//cerr<<u<<" "; q.pop(); if(!c[u]) c[u]=1,c[id[u]]=2; for(int i=h[u];i;i=e[i].ne) if(!(--du[e[i].to])) q.push(e[i].to); } for(int i=2;i<=n;i++) { if(c[bl[i]]==c[bl[1+n]]) printf("%dh ",i-1); else printf("%dw ",i-1); } puts(""); } return 0; }