HDU---1814:Peaceful Commission【2-SAT---最小字典序的解】

博客探讨了如何解决HDU 1814题目的2-SAT问题,即在存在矛盾的团队中选出和平委员会,使得成员间无矛盾,同时求解字典序最小的解。文章介绍了通过暴力枚举结合栈来避免矛盾的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:

有n个团队,每个团队有2个人,有m对人之间存在矛盾,问能否在每个团队中只选出一个人组成n个人的和平委员会,并且他们之间不存在有矛盾的人,若能,输出字典序最小的解

分析:

网上基本都是暴力枚举的,没见过更好的算法

对每个团队,优先枚举编号较小的,再把所有必须选择的标记了,将它们存入栈里,如果出现矛盾了,说明这条路行不通,将栈里的取消标记即可

代码:

#include <bits/stdc++.h>

using namespace std;
const int MAXN = 2e4+14;
int head[MAXN],mark[MAXN],Stack[MAXN],n,m,a,b,cnt,top;
struct edge
{
    int to,nxt;
} e[MAXN<<1];
void add(int u,int v)
{
    e[++cnt].to = v;
    e[cnt].nxt = head[u];
    head[u] = cnt;
}
bool dfs(int x)
{
    mark[x] = 1;
    Stack[++top] = x;
    if(mark[x^1]) return false;
    for(int i = head[x]; i ; i = e[i].nxt)
    {
        if(mark[e[i].to]) continue;
        if(!dfs(e[i].to)) return false;
    }
    return true;
}
bool solve()
{
    for(int i = 0; i < (n<<1); i += 2)
    {
        if(!mark[i] && !mark[i^1])
        {
            top = 0;
            if(!dfs(i))
            {
                while(top--) mark[Stack[top]] = 0;
                if(!dfs(i^1)) return false;
            }
        }
    }
    return true;
}
void init()
{
    cnt = 0,
    memset(mark,0,sizeof(mark));
    memset(head,0,sizeof(head));
}
int main()
{
    while(cin >> n >> m)
    {
        init();
        while(m --)
        {
            cin >> a >> b;
            a--,b--;                         //方便操作
            add(a,b^1);
            add(b,a^1);
        }
        if(solve())
        {
            for(int i = 0; i < (n<<1); i+=2)
            {
                if(mark[i]) cout << i+1 <<'\n';
                else cout << (i^1)+1 << '\n';
            }
        }
        else puts("NIE");
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值