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;
}

猜你喜欢

转载自www.cnblogs.com/AKCqhzdy/p/9556796.html