poj3648 Wedding
又被神仙的2-set卡死了。思路大错特错,思维僵化把夫妇分集合,即使了解到正确的做法,也没有意识到夫妻之间建边,真是惭愧。
看看注释吧,不想说话。
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();} while('0'<=ch&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return 2*(x+1)*f+(ch=='w'); } int n; void pr(int d,int w) { printf("%d",d/2-1); if(w^(d%2==0))printf("h"); else printf("w"); } struct node { int x,y,next; }a[210000];int len,last[11000]; void ins(int x,int y) { len++; a[len].x=x;a[len].y=y; a[len].next=last[x];last[x]=len; } int z,dfn[11000],low[11000]; int top,sta[11000];bool v[11000]; int cnt,bel[11000]; void SCC(int x) { dfn[x]=low[x]=++z; sta[++top]=x;v[x]=true; for(int k=last[x];k;k=a[k].next) { int y=a[k].y; if(dfn[y]==0) { SCC(y); low[x]=min(low[x],low[y]); } else if(v[y]==true) low[x]=min(low[x],dfn[y]); } if(low[x]==dfn[x]) { int k;cnt++; do { k=sta[top];top--; v[k]=false; bel[k]=cnt; }while(k!=x); } } int as[11000]; int main()//对于编号,1~2n表示和新娘同侧,进则反之,偶数编号表男性,奇数反之 { int m,x,y; while(scanf("%d%d",&n,&m)!=EOF) { if(n==0&&m==0)break; len=0;memset(last,0,sizeof(last)); ins(2+2*n,3), ins(2,2+2*n);//新郎必须和新娘异侧 ins(3+2*n,3), ins(3,2+2*n);//新娘无法和自己异侧 for(int i=2;i<=n;i++)//夫妻不能坐同一侧 { ins(i*2,i*2+1+2*n), ins(i*2+1+2*n,i*2); ins(i*2+1,i*2+2*n), ins(i*2+2*n,i*2+1); } for(int i=1;i<=m;i++) { x=read(),y=read(); ins(y+2*n,x);//x,y不能同时不同侧,分别确定x、y不同侧,另一个必须同侧 ins(x+2*n,y); } z=cnt=top=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(v,false,sizeof(v)); for(int i=2;i<=4*n+1;i++) if(dfn[i]==0)SCC(i); bool bk=true; for(int i=2;i<=2*n+1;i++) { if(bel[i]==bel[i+2*n]){bk=false;break;} if(bel[i]>bel[i+2*n])as[i/2]=i; } if(bk==false)printf("bad luck\n"); else { int w=(as[1]%2==0); for(int i=2;i<n;i++)pr(as[i],w),printf(" "); pr(as[n],w),printf("\n"); } } return 0; }
pain and happy in the cruel world.