2-sat——暴力染色输出方案hdu1814

因为要求输出字典序最小的解,所以用暴力染色

具体有点像二分图染色

遍历0-2*n-1个点,尝试将每个点染成1,该点所能到达的所有点都要染成1

如果不行,则把上该点的影响消除,再把对立点染成1,如果还不行就无解

#include<bits/stdc++.h>
#include<vector>
using namespace std;
#define maxn 200005
vector<int>G[maxn];
int n,m,stk[maxn],top,mark[maxn];

bool dfs(int x){
    if(mark[x^1])return false;
    if(mark[x])return true;
    mark[x]=true;
    stk[top++]=x;
    for(int i=0;i<G[x].size();i++)
        if(!dfs(G[x][i]))return false;
    return true;
}
bool work(){
    for(int i=0;i<2*n;i+=2)
        if(!mark[i] && !mark[i+1]){
            top=0;
            if(!dfs(i)){//如果给i染色为1不成立 
                while(top)//把栈里的染色清空 
                    mark[stk[--top]]=0;
                if(!dfs(i+1))return false; 
            }
        }
    return 1;
}

int main(){
    while(cin>>n>>m){
        for(int i=0;i<maxn;i++)
            G[i].clear();
        int x,y;
        for(int i=0;i<m;i++){
            cin>>x>>y;--x;--y;
            G[x].push_back(y^1);
            G[y].push_back(x^1);
        }
        memset(mark,0,sizeof mark);
        top=0;
        if(!work())puts("NIE");
        else {
            for(int i=0;i<2*n;i++)
                if(mark[i])cout<<i+1<<endl;
        }
    }
}
原文地址:https://www.cnblogs.com/zsben991126/p/10877876.html