【2-SAT】POJ 3648

來源:互聯網
上載者:User

題意:一對新婚的夫婦邀請(n-1)對夫婦來參加自己的宴會,這對新人以及這些受邀請的夫婦都坐在長桌子的兩邊,新娘和新郎分別坐在桌子的兩側,新娘不希望看到她邀請來的那些夫婦之中有妻子和丈夫坐在同一邊的情況(即妻子和丈夫要分作桌子的兩邊),在這n對夫婦中有一些男女存在著曖昧的關係,所以新娘也不希望看到有曖昧關係的人坐在她對面的那一側.求解是否存在一種滿足新娘要求的座位分配方案,如果存在的話,那麼就輸出這方案,否則輸出"bad
luck".

    新娘編號為0,新郎編號為1,即將妻子編號為2*i,丈夫編號為2*i+1,對於曖昧關係x y,加邊x->y', y->x',因為需要輸出和新娘坐在同一邊的方案,所以這裡應該以新娘為標準得到需要的解,這裡由於新郎和新娘不能坐在同一邊,所以加邊0->1.

#define N 1004vector<int> v[N];vector<int> g[N];stack<int> s;bool vis[N];bool inStack[N];int low[N],dfn[N];int belong[N];//屬於哪個強連通分量int n,m,step,t;int conflict[N];int col[N];int in[N];void init(){    int i;    for(i=0;i<=2*n;i++){        v[i].clear();        vis[i] = 0;        inStack[i] = 0;        in[i] = 0;        g[i].clear();        col[i] = 0;    }    while(!s.empty())s.pop();}void add(int a,int b){    v[a].push_back(b);}//tarjan縮點void tarjan(int u){    vis[u]=true;    step++;    s.push(u);    inStack[u]=true;    low[u]=step,dfn[u]=step;    int i,j;    for(i=0;i<v[u].size();i++)    {        int x=v[u][i];        if(!vis[x])        {            tarjan(x);            low[u]=min(low[u],low[x]);        }        else        if(inStack[x])        low[u]=min(low[u],dfn[x]);    }    if(low[u]==dfn[u])    {        t++;        while(1)        {            int x=s.top();            s.pop();            belong[x]=t;            inStack[x]=false;            if(x==u)break;        }    }}//反向建圖,因為最後是自底向上拓撲,因此反向後就變成了一般的自上向下拓撲,方便實現void rebuild(){    int i,j;    for(i=0;i<2*n;i++){        for(j=0;j<v[i].size();j++){            int a = belong[i],b = belong[v[i][j]];            if(a!=b){                in[a]++;                g[b].push_back(a);            }        }    }}void topsort(){    int i,j;    queue<int> qq;    for(i=1;i<=t;i++){//現在對縮點後的圖進行拓撲        if(!in[i]){            qq.push(i);        }    }    while(!qq.empty()){        int u = qq.front();qq.pop();        if(!col[u]){            col[u] = 1;//紅色            col[conflict[u]] = 2;//藍色(因為縮點後變成有向非循環圖,對應的衝突點只有確定的一個)        }        for(i=0;i<g[u].size();i++){            int vv = g[u][i];            in[vv]--;            if(!in[vv])qq.push(vv);        }    }}void solve(){    t = 0,step = 0;    int i,j;    for(i=0;i<2*n;i++){        if(!vis[i])tarjan(i);    }    for(i=0;i<2*n;i+=2){        if(belong[i] == belong[i+1]){//矛盾點在同一個強連通分量            puts("bad luck");            return ;        }        int a = belong[i],b = belong[i+1];        conflict[a] = b;        conflict[b] = a;    }    rebuild();    topsort();    for(i=2;i<2*n;i+=2){        if(i!=2)printf(" ");        if(col[belong[i]] == col[belong[0]]){//如果女的與新娘同色,就取她            printf("%dw",i/2);        } else printf("%dh",i/2);//否則,取她的老公    }    puts("");}int main(){    while(scanf("%d%d",&n,&m) && (n+m)){        int i,j,ii,jj;        init();        char c1,c2;        int d1,d2;        while(m--){            scanf("%d%c %d%c",&d1,&c1,&d2,&c2);            if(c1 == 'h'){                i = 2*d1+1;//man                ii = i-1;//woman            } else {                i = 2*d1;//woman                ii = i+1;//man            }            if(c2 == 'h'){                j = 2*d2+1;//man                jj = j-1;//woman            } else {                j = 2*d2;//woman                jj = j+1;//man            }            add(i,jj);//i->j'            add(j,ii);//j->i'            //cout<<i<<" "<<ii<<endl;            //cout<<j<<" "<<jj<<endl<<endl;        }        add(0,1);        solve();    }    return 0;}






聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.