poj3648Wedding【2-SAT】输出任意解

来源:互联网 发布:mac谷歌浏览器安装 编辑:程序博客网 时间:2024/04/20 07:27

Total Submissions: 9574  Accepted: 2908 Special Judge

Description

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.

Input

The input consists of a number of test cases, followed by a line containing 0 0. Each test case givesn, 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 ton - 1 with the bride and groom being 0w and 0h.

Output

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

Sample Output

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

Source

Waterloo Local Contest, 2007.9.29

题意:

一堆夫妇去参加一对新人的婚礼。人们坐在一个很长很长的桌子的两侧(面对面)。新郎新娘在桌子头面对面座。

新娘不希望看见她对面的一排有一对夫妇坐着(夫妇需要分开两排座)。

同时,一些人之间有通奸关系(通奸不分性别,而且新郎新娘也可能通奸!!!!),新娘也不希望有通奸关系的人同时坐在她对面的一排。

问你可否满足新娘的要求,可以的话,输出一种方案

做法:和hdu1814Peaceful Commission【2-SAT】输出最小解   一模一样,实在不理解为啥非得强连通分量缩点,反向拓扑排序……

这个题套入2-sat的真假有点绕,我们假设新娘这侧选h是“真”(i),选"w"是假(i+n),那么h-h加边就是b+n->a a+n->b ; w-h : a->b  b+n->a+n ; w-w : a->b+n  b->a+n ; h-w : b->a a+n->b+n

还有据说新郎也可能和别人通奸,新娘设为0,新郎设成n,再连一个0->n(他俩位置得固定下来啊,,,这么连边也满足我上面的推理)

注意不要用%s,貌似数据的通奸关系中间可能没有空格

还有就是和hdu1814一样的问题,if条件写一个写两个都对,我感觉应该写两个啊==

/*************poj36482016.7.27452K0MSC++2038B************/#include <iostream>#include<cstring>#include<cstdio>#include<vector>using namespace std;#define maxn 8004struct TWOSAT{    int n;    vector<int>G[maxn*2];    bool mark[maxn*2];    int S[maxn*2],c;    bool dfs(int x)    {        if(mark[x+n])return false;        if(mark[x]) return true;        mark[x]=true;        S[c++]=x;        for(int i=0;i<G[x].size();i++)            if(!dfs(G[x][i])) return false;        return true;    }    void init(int n)    {        this->n=n;        for(int i=0;i<n*2;i++) G[i].clear();        memset(mark,0,sizeof(mark));    }    void add_clause(int x,int y)    {        G[x].push_back(y);       // G[y].push_back(x);///不一定是+1、-1!!而且本身就2n不用乘以2    }    bool solve()    {        for(int i=0;i<n;i++)        {            if(!mark[i]&&!mark[i+n])            {                c=0;                if(!dfs(i))                {                    while(c>0) mark[S[--c]]=false;                    if(!dfs(i+n)) return false;                }            }        }        return true;    }}solver;int n,m;int main(){   // freopen("cin.txt","r",stdin);    while(~scanf("%d%d",&n,&m))    {        solver.init(n);        for(int i=0;i<m;i++)        {            int a,b;            char c1,c2;            scanf("%d%c%d%c",&a,&c1,&b,&c2);            if(c1=='h'&&c2=='h')                solver.add_clause(a+n,b),solver.add_clause(b+n,a);            if(c1=='h'&&c2=='w')                solver.add_clause(a+n,b+n),solver.add_clause(b,a);            if(c1=='w'&&c2=='h')                solver.add_clause(a,b),solver.add_clause(b+n,a+n);            if(c1=='w'&&c2=='w')                solver.add_clause(a,b+n),solver.add_clause(b,a+n);        }        solver.add_clause(0,n);        if(!solver.solve()) puts("bad luck");        else        {            for(int i=1;i<n;i++)            {                if(solver.mark[i]&!solver.mark[i+n]) printf("%dh ",i);                //452K16MSC++2122B if后面的条件加上的话                else printf("%dw ",i);            }            puts("");        }    }    return 0;}



0 0
原创粉丝点击