Let's go home HDU - 1824 (2-sat以及案例1解释)

版权声明:本人蒟蒻,如有大佬转发,感激不尽,带上我的博客链接即可。 https://blog.csdn.net/qq_36300700/article/details/81946051

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1824

Sample Input
1 2
0 1 2
0 1
1 2

Sample Output
yes

解释案例: 1号和2号队员回家,0号队长留下来。(题目每一对队员,两个是可以同时回家的)。

ac代码:

#include <iostream>
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>

using namespace std;

const int maxn =10000+50;

vector<int>G[maxn];
bool mark[maxn];

int S[maxn],c;
int T,M,n;

void init()///初始化
{
    n=3*T;
    for(int i=0; i<n*2; i++)
        G[i].clear();
    memset(mark,0,sizeof(mark));

}

void add_clause(int x, int xval, int y, int yval)///建边
{
    x=x*2+xval;
    y=y*2+yval;
    G[x^1].push_back(y);
    G[y^1].push_back(x);
}


bool dfs(int x)
{
    if(mark[x^1])
        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;
}

bool solve()
{
    for(int i=0; i<n*2; 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;
}

int main()
{
    while(scanf("%d %d",&T,&M)!=EOF)
    {
        init();
        int x,y,z;///x为队长 y,z为队员
        for(int i=1; i<=T; i++)
        {
            scanf("%d %d %d",&x,&y,&z);
            add_clause(x,1,y,1);/// (x不回,y回),(y不回,x回)
            add_clause(x,1,z,1);/// (x不回,z回),(z不回,x回)

            add_clause(y,0,x,0);/// (y回,x不回),(x回,y不回)
            add_clause(z,0,x,0);/// (z回,x不回),(x回,z不回)

            add_clause(y,1,z,0);/// (y不回,z不回),(z回,y回)
            add_clause(y,0,z,1);/// (y回,z回 ),(z不回,y不回)


        }

        for(int i=1; i<=M; i++)
        {
            scanf("%d %d",&x,&y);
            add_clause(x,1,y,1);/// (x不回,y回),(y不回,x回)
        }

        if(solve())
        {
            printf("yes\n");
        }

        else
        {
            printf("no\n");
        }
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_36300700/article/details/81946051