HDU 1814 Peaceful Commission(2-sat 输出字典序最小解 )

dfs求字典序最小的2-sat解方法:

如果原图中的同一对点编号都是连续的(01、23、45……)则可以依次尝试第0对、第1对……点,每对点中先尝试编号小的,若失败再尝试编号大的。这样一定能求出字典序最小的解(如果有解的话),因为一个点一旦被确定,则不可更改。

如果原图中的同一对点编号不连续(比如03、25、14……)则按照该对点中编号小的点的编号递增顺序将每对点排序,然后依次扫描排序后的每对点,先尝试其编号小的点,若成功则将这个点选上,否则尝试编号大的点,若成功则选上,否则(都失败)无解。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;

const int N = 16100;
const int MAXM = 40200;

int n,m;
bool mark[N];
int sta[N],top;
struct Edge
{
    int v,next;
}es[MAXM];
int head[N];
int cnt=0;
inline void add_edge(int u,int v)
{
    es[++cnt].v=v;
    es[cnt].next=head[u];
    head[u]=cnt;
}
bool dfs(int u)
{
    if(mark[u^1]) return false;
    if(mark[u]) return true;
    sta[++top]=u;
    mark[u]=1;
    for(int i=head[u];~i;i=es[i].next)
    {
        int v=es[i].v;
        if(dfs(v)==false) return false;
    }
    return true;
}
bool judge()
{
    for(int i=0;i<2*n;i++)
    {
        if(!mark[i]&&!mark[i^1])
        {
            top=0;
            if(dfs(i)==false)
            {
                for(int j=1;j<=top;j++)
                    mark[sta[j]]=0;
                top=0;
                if(dfs(i^1)==false) return false;
            }
        }
    }
    return true;
}
void ini()
{
    memset(mark,0,sizeof(mark));
    memset(head,-1,sizeof(head));
    cnt=top=0;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        ini();
        for(int i=1;i<=m;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            u--,v--;
            add_edge(u,v^1);
            add_edge(v,u^1);
        }
        if(judge())
        {
            for(int i=0;i<2*n;i++)
                if(mark[i]) printf("%d\n",i+1);
        }
        else puts("NIE");
    }
    return 0;
}
时间: 2024-10-11 01:57:01

HDU 1814 Peaceful Commission(2-sat 输出字典序最小解 )的相关文章

hdu 1814 Peaceful Commission (2-sat 输出字典序最小路径)

Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1948    Accepted Submission(s): 560 Problem Description The Public Peace Commission should be legislated in Parliament of Th

HDU 1814 Peaceful Commission(2-sat)

HDU 1814 Peaceful Commission 题目链接 题意: 根据宪法,Byteland民主共和国的公众和平委员会应该在国会中通过立法程序来创立. 不幸的是,由于某些党派代表之间的不和睦而使得这件事存在障碍. 此委员会必须满足下列条件: 每个党派都在委员会中恰有1个代表, 如果2个代表彼此厌恶,则他们不能都属于委员会. 每个党在议会中有2个代表.代表从1编号到2n. 编号为2i-1和2i的代表属于第I个党派. 任务 写一程序: 从文本文件读入党派的数量和关系不友好的代表对, 计算决

HDU 1814 Peaceful Commission

Peaceful Commission Time Limit: 5000ms Memory Limit: 32768KB This problem will be judged on HDU. Original ID: 181464-bit integer IO format: %I64d      Java class name: Main The Public Peace Commission should be legislated in Parliament of The Democra

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解决方式)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 Problem Description The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byteland according to The Very Important Law. Unfortunately one of the obstacles is t

HDU 1814 Peaceful Commission(2-sat 模板题输出最小字典序解)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 Problem Description The Public Peace Commission should be legislated in Parliament of The Democratic Republic of Byteland according to The Very Important Law. Unfortunately one of the obstacles is t

【HDU】1814 Peaceful Commission

http://acm.hdu.edu.cn/showproblem.php?pid=1814 题意:n个2人组,编号分别为2n和2n+1,每个组选一个人出来,且给出m条关系(x,y)使得选了x就不能选y,问是否能从每个组选出1人.且输出字典序最小的答案.(n<=8000, m<=20000) #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #in

HDOJ 1814 Peaceful Commission

经典2sat裸题,dfs的2sat能够方便输出字典序最小的解... Peaceful Commission Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1578    Accepted Submission(s): 406 Problem Description The Public Peace Commission should

【HDOJ】1814 Peaceful Commission

2-SAT基础题目. 1 /* 1814 */ 2 #include <iostream> 3 #include <vector> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cstring> 7 #include <cstdlib> 8 using namespace std; 9 10 #define MAXN 8005 11 12 vector<int>

HDU 1848 2SAT 输出字典序最小

告诉你两两冲突的序列,让输出字典序最小. 一开始老老实实tarjan,写完了发现后面完全不能好弄,因为选了第一个点,你没办法快速找出全部对立组,只能找出本来在一个pair中的那个对立组,而找不出给定的那个随意的对立组.所以直接从1开始染色,弄不出来就染2.以此类推. 这个题还有一个教训就是,点要多开一倍,边也要多开一倍.老是忘... #include<algorithm> #include<iostream> #include<cstdio> #include<c