uva11294 - Wedding

来源:互联网 发布:oa软件核心应用价值 编辑:程序博客网 时间:2024/05/21 15:06

Problem E: Wedding

Up to thirty couples will attend a wedding feast, at which they will be seated on either side of a long table. The bride and groom sit at one end, opposite each other, and the bride wears an elaborate headdress that keeps her from seeing people on the same side as her. It is considered bad luck to have a husband and wife seated on the same side of the table. Additionally, there are several pairs of people conducting adulterous relationships (both different-sex and same-sex relationships are possible), and it is bad luck for the bride to see both members of such a pair. Your job is to arrange people at the table so as to avoid any bad luck.

The input consists of a number of test cases, followed by a line containing 0 0. Each test case gives n, the number of couples, followed by the number of adulterous pairs, followed by the pairs, in the form "4h 2w" (husband from couple 4, wife from couple 2), or "10w 4w", or "3h 1h". Couples are numbered from 0 to n-1 with the bride and groom being 0w and 0h. For each case, output a single line containing a list of the people that should be seated on the same side as the bride. If there are several solutions, any one will do. If there is no solution, output a line containing "bad luck".

Sample Input

10 63h 7h5w 3w7h 6w8w 3w7h 3w2w 5h0 0

Possible Output for Sample Input

1h 2h 3w 4h 5h 6h 7h 8h 9h

Prabhakar Ragde



一道标准的2-sat 但是很绕,
每对夫妻不能坐同一侧,
吵过架的m对,每对不能同时坐在新娘的对面,
所以考虑如何选人坐在新娘对面,
添加g[0][1]这一条边表示丈夫必须坐在对面

2*x表示第x对的妻子,2*x+1表示第x对的丈夫



具体的2-sat解法没有什么问题
建边-->求强连通分量-->判断是否 x和!x在同一个强连通分量,有即结束
-->反向建图-->拓扑排序并标记-->得到一种解
但是2-sat主要会卡在建边上,如何建边构造模型是2-sat的关键点



#include<cstdio>#include<cstring>#include<iostream>#include<stack>#include<queue>using namespace std;#define N 200int dfn[N],low[N],scc[N];int ha[N],ans[N],in[N];vector <int> g[N];vector <int> dag[N];stack <int> S;queue <int> Q;int n,m,idx,cnt;void tarjan(int u){    dfn[u]=low[u]=++idx;    S.push(u);    for (int i=0; i<g[u].size(); i++)    {        int v=g[u][i];        if (!dfn[v])        {            tarjan(v);            low[u]=min(low[u],low[v]);        }        else            if (!scc[v])                low[u]=min(low[u],dfn[v]);    }    if (low[u]==dfn[u])    {        cnt++;        while (1)        {            int x=S.top();            S.pop();            scc[x]=cnt;            if(x==u) break;        }    }}void build_Dag(){    for (int i=1; i<=cnt; i++)        dag[i].clear();    for (int u=0; u<2*n; u++)        for (int i=0; i<g[u].size(); i++)        {            int v=g[u][i];            if(scc[v]!=scc[u])            {                dag[scc[v]].push_back(scc[u]);                in[scc[u]]++;            }        }}void topsort(){    for (int i=1; i<=cnt; i++)        if (!in[i])  Q.push(i);    while (!Q.empty())    {        int u=Q.front();        Q.pop();        if (!ans[u])        {            ans[u]=1;            ans[ha[u]]=2;        }        for (int i=0; i<dag[u].size(); i++)        {            int v=dag[u][i];            in[v]--;            if (!in[v]) Q.push(v);        }    }    //cout<<ans[scc[0]]<<endl;    for (int i=2; i<2*n; i++)    {        if (ans[scc[i]]==ans[scc[0]])        {            if (i%2==0)                printf("%dw ",i/2);            else                printf("%dh ",i/2);        }    }    printf("\n");}int main(){    while (1)    {        scanf("%d%d",&n,&m);        if (n==0&&m==0) break;        for (int i=0; i<N; i++)            g[i].clear();        g[0].push_back(1);        for (int i=0; i<m; i++)        {            int x,y;            char c1,c2;            scanf("%d%c %d%c",&x,&c1,&y,&c2);            int a0,b0,a1,b1;            if (c1=='w')            {                a0=2*x;                a1=2*x+1;            }            else            {                a0=2*x+1;                a1=2*x;            }            if (c2=='w')            {                b0=2*y;                b1=2*y+1;            }            else            {                b0=2*y+1;                b1=2*y;            }            g[a0].push_back(b1);            g[b0].push_back(a1);        }        memset(dfn,0,sizeof(dfn));        memset(low,0,sizeof(low));        memset(scc,0,sizeof(scc));        memset(ans,0,sizeof(ans));        memset(ha,0,sizeof(ha));        memset(in,0,sizeof(in));        cnt=idx=0;        for (int i=0; i<2*n; i++)            if (!dfn[i])                tarjan(i);        bool flag=0;        for (int i=0; i<n; i++)        {            if (scc[2*i]==scc[2*i+1])                flag=1;            else            {                ha[scc[2*i]]=scc[2*i+1];                ha[scc[2*i+1]]=scc[2*i];            }        }        if (flag)            printf("bad luck\n");        else        {            build_Dag();            topsort();        }    }    return 0;}


原创粉丝点击