uva 11294 2-SAT问题

来源:互联网 发布:显卡真假软件 编辑:程序博客网 时间:2024/05/22 16:49

英文太差了, 这个题目愣是半天没看懂 , 后面看别人翻译才看懂 ,  英语是硬伤啊


题目大意:给 n 对夫妇安排座位 , 0h , 0w表示新郎新娘 , 新娘只能看到坐在她对面那一排的人 , 要求:

1、同一对新郎新娘不能做在同一侧

2、有m对人互为通奸(可以男男、女女、男女) , 新娘不能同时看到互为通奸的两个人。


注意:新郎也有可能和其他人通奸


做法:

1、分两种情况讨论 , 新娘在左侧 , 新娘在右侧 , 分别建图进行 2-SAT算法

2、不分左侧还是右侧 , 只分和新娘同侧或不同侧


下面给出做法一的代码

#include <iostream>#include <vector>#include <stdio.h>#include <string.h>using namespace std;#define maxn 200000int n , m;int a[maxn][2];vector<int>grap[maxn];bool mark[maxn];int s[maxn];int c;void init(){    memset(mark , 0 , sizeof(mark));    for(int i = 0; i < 4*n; i++)        grap[i].clear();}void add_edge(int x , int y){    grap[x].push_back(y);    //cout<<x<<",,"<<y<<endl;}bool dfs(int u){    if(mark[u^1])  return false;    if(mark[u])  return true;    mark[u] = true;    s[c++] = u;    for(int i = 0; i < grap[u].size(); i++)    {        if(!dfs(grap[u][i]))  return false;    }    return true;}bool slove(){    int i;    for(i = 0; i < n*4; i += 2)    {        if(!mark[i] && !mark[i+1])        {            c = 0;            if(!dfs(i))            {                while(c > 0) mark[s[--c]] = false;                if(!dfs(i+1))  return false;            }        }    }    return true;}void print(int i){    int bz = true;    for( ; i < 4*n ; i += 2)    {        if(i == 2*n || i == 2*n+1)  continue;        if(mark[i])        {           if(i >= 2*n)            {                if(bz)  printf("%dh" , (i-2*n)/2) , bz = false;                else printf("% dh" , (i-2*n)/2);            }            else            {                if(bz)  printf("%dw" , i/2) , bz = false;                else printf("% dw" , i/2);            }        }    }    cout<<endl;}int main(){    while(scanf("%d %d" , &n , &m) != EOF)    {        if(n == 0 && m == 0)  break;        //n -= 1;        init();        int i ;        int x , y;        char px , py;        for(i = 0; i < m; i++)        {            scanf("%d%c %d%c" , &x , &px , &y , &py);            //x -= 1; y -= 1;            if(px == 'h')  a[i][0] = 2*n+x*2;            else a[i][0] = x*2;            if(py == 'h')  a[i][1] = 2*n+y*2;            else a[i][1] = y*2;        }        for(i = 2; i < 2*n; i += 2) //夫妻之间        {            add_edge(i , 2*n+i+1);            add_edge(2*n+i+1,i  );            add_edge(i+1 , 2*n+i);            add_edge(2*n+i , i+1);        }        for(i = 0; i < m; i++)  //仇人之间        {            add_edge(a[i][0]+1 , a[i][1]);            add_edge(a[i][1]+1 , a[i][0]);        }        mark[0] = mark[2*n+1] = true;        bool bz = slove();        if(!bz)        {            init();            for(i = 0; i < 2*n; i += 2) //夫妻之间            {                add_edge(i , 2*n+i+1);                add_edge(2*n+i+1 ,i  );                add_edge(i+1 , 2*n+i);                add_edge(2*n+i , i+1);            }            for(i = 0; i < m; i++)  //仇人之间            {                add_edge(a[i][0] , a[i][1]+1);                add_edge(a[i][1] , a[i][0]+1);            }            mark[1] = mark[2*n] = true;            bz = slove();            if(!bz)  printf("bad luck\n");            else            {                print(3);            }        }        else        {            print(2);        }    }    return 0;}


0 0
原创粉丝点击