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

题意:给出一个数n,代表有n个党派,每个党派要求派出其中一个人去参加会议,且只能派出一人。给出m,m行每行给出a, b.代表处于不同党派中的a, b也具有矛盾关系,a, b其中也只能有一位去参加会议。这2 * n个人的编号为1 ~ 2 * n,其中 2 * i 与 2 * i - 1是属于同一个党派。要求找到一个编号字典序最小的方案。

思路:

1.每个集合中只有2个元素,并且给出部分元素之间的限制关系,典型的2-sat问题。

2.找到对立点,建‘矛盾边’,用tarjan缩点,再判断对立点是否处在一个强连通分量中,若处在则无解,若都不处在就有解。这种思路在这道题是不可行的,因为题目要求最小字典序输出。

3.由于要保证最小字典序,我们可以用染色法来求解。每个人的编号我们默认 -1 ,这样就可以运用 ^1 运算来处理同一帮派中的2个人。从0号开始遍历到2 * n - 1号人,这样寻找方案就是最小字典序。

4.扩展:若同一对点的编号是不连续的,例如0-5,1-9,3-4. 那么我们就要用结构体排序(结构体中2个变量分别代表同一帮派中的2个人的编号),将同一点对中小的那个点按照从小到大的顺序排序,保证遍历的时候的字典序。(加矛盾边不需要处理)

代码里的注释很详细。

 #include<stdio.h>
#include<string.h>
#define mem(a, b) memset(a, b, sizeof(a)) int n, m;
int head[], cnt;
int vis[], sum, node[]; struct Edge
{
int to, next;
}edge[ * ]; void add(int a, int b)
{
edge[++ cnt].to = b;
edge[cnt].next = head[a];
head[a] = cnt;
} void init()
{
mem(head, -), cnt = ;
mem(vis, );
} int dfs(int now)
{
if(vis[now ^ ])//若帮派中另一个人已经被选择,则自己一定不会被选择,返回0
return ;
if(vis[now])//若自己已经被选择,则不用再dfs了,已经找过从自己出发的方案
return ;
node[sum ++] = now;//记录查找过程中的点是哪些
vis[now] = ;
for(int i = head[now]; i != -; i = edge[i].next)//不同帮派中的矛盾关系
{
int to = edge[i].to;
if(!dfs(to))//这些边代表'必须', 不能选b,就必须选择b ^ 1,若b ^ 1找不到合理方案,说明就不存在方案了,返回0
return ;
}
return ;
} int two_sat() //返回是否存在方案
{
for(int i = ; i < * n; i += ) //由小到大遍历, 保证在有合理的方案的情况下的字典序
{
if(!vis[i] && !vis[i ^ ]) //若遍历到有帮派中2人都未被标记, 则确定之前的标记,代表是合法方案的一部分, sum清为0
{
sum = ;
if(!dfs(i))//暴力寻找的过程中发现不存在,那么该过程中被标记的点都重新处理为未被标记
{
while(sum)
vis[node[-- sum]] = ;
if(!dfs(i ^ ))//若帮派中另一个人也找不到合理方案,那么就不存在方案了,直接retrun 0
return ;
}
}
}
return ;
} int main()
{
while(scanf("%d%d", &n, &m)!=EOF)
{
init();
for(int i = ; i <= m; i ++)
{
int a, b;
scanf("%d%d", &a, &b);
a --, b --; //形成 ^1 运算关系
add(a, b ^ ), add(b, a ^ );
}
if(two_sat())
{
for(int i = ; i < * n; i += )
{
if(vis[i])
printf("%d\n", i + );
else
printf("%d\n", (i ^ ) + );
}
}
else
printf("NIE\n");
}
return ;
}

HDU1814(Peaceful Commission) 【2-SAT DFS暴力求最小字典序的模板】的更多相关文章

  1. Codeforces 959 树构造 暴力求最小字典序互质序列

    A B C 题目给你一个结论 最少需要min((odd,even)个结点可以把一棵树的全部边连起来 要求你输出两颗树 一棵树结论是正确的 另外一棵结论是正确的 正确结论的树很好造 主要是错误的树 题目 ...

  2. hdu1814 Peaceful Commission

    hdu1814 Peaceful Commission 题意:2-sat裸题,打印字典序最小的 我写了三个 染色做法,正解 scc做法,不管字典序 scc做法,错误的字典序贪心 #include &l ...

  3. HDU1814 Peaceful Commission 2-sat

    原文链接http://www.cnblogs.com/zhouzhendong/p/8099115.html 题目传送门 - HDU1814 题面 Description 根据宪法,Byteland民 ...

  4. HDU-1814 Peaceful Commission 2sat

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 简单的2sat题. //STATUS:C++_AC_390MS_996KB #include & ...

  5. hdu1814 Peaceful Commission,2-sat

    题目大意:一国有n个党派.每一个党派在议会中都有2个代表,现要组建和平委员会,要从每一个党派在议会的代表中选出1人,一共n人组成和平委员会.已知有一些代表之间存在仇恨,也就是说他们不能同一时候被选为和 ...

  6. hdu1814 Peaceful Commission——2-SAT

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1814 第一次的2-SAT,推荐博客:https://blog.csdn.net/jarjingx/arti ...

  7. poj 3009 冰球 【DFS】求最小步数

    题目链接:https://vjudge.net/problem/POJ-3009 转载于:https://www.cnblogs.com/Ash-ly/p/5728439.html 题目大意: 要求把 ...

  8. poj1509(环形字符串求最小字典序)

    题意:给你一串字符串,但是这串字符串是环形的,让你找个位置切开,使得它的字典序最小....... 思路:典型的最小表示法....... #include<iostream> #includ ...

  9. BZOJ4974(给Next求最小字典序原串)

    输入给出了最小循环节长度,暗示next数组. 然后自己按照自己的kmp板子逆着来一遍就好. ; int n, a, Next[maxn]; char str[maxn]; ]; int main() ...

随机推荐

  1. pycharm mysql数据源配置、SQL方言配置

    会发现有提示,看着不爽,但不影响运行程序, 这里提示没有配置数据源,现在配置MYSQL数据源 然后看到右边Database选项卡,点击 然后可能会出现网络防火墙提示,选择全部允许,之后可能会在pych ...

  2. js中showModalDialog的使用

    基本介绍:          showModalDialog()         (IE 4+ 支持)          showModelessDialog()      (IE 5+ 支持)    ...

  3. printf:函数参数计算从右向左,从左向右?

    造冰箱的大熊猫@cnblogs 2019/8/3 1.问题 某天写了如下代码: unsigned char ReadByteFromFile ( FILE * fp ) { unsigned char ...

  4. noi 第n小的质数

    总时间限制:  1000ms 内存限制:  65536kB 描述 输入一个正整数n,求第n小的质数. 输入 一个不超过10000的正整数n. 输出 第n小的质数. 样例输入 10 样例输出 29 一定 ...

  5. Python数据抓取(3) —抓取标题、时间及链接

    本次分享,jacky将跟大家分享如何将第一财经文章中的标题.时间以及链接抓取出来 (一)观察元素抓取位置 网页的原始码很复杂,我们必须找到特殊的元素做抽取,怎么找到特殊的元素呢?使用开发者工具检视每篇 ...

  6. JS判断开始时间不能大于检查结束时间

    //用来检验检查开始时间不能大于检查结束时间 function checkDate(date){ var startDate = $("#jcrwModel_rwfqsj").va ...

  7. MAC ADDRESS

    可以使用手机Wifi或蓝牙的MAC地址作为设备标识,但是并不推荐这么做,原因有以下两点:硬件限制:并不是所有的设备都有Wifi和蓝牙硬件,硬件不存在自然也就得不到这一信息.获取的限制:如果Wifi没有 ...

  8. Java-AQS源码详解(细节很多!)

    ReentrantLock调用lock()时时序图: addWaiter方法: enq方法:自旋 它维护了一个volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用 ...

  9. php 设置error_reporting(0)和ini_set('display_errors', 0)之后,还是显示错误

    php 5.4 apache 2.2 关闭错误报告和错误显示 依然会显示错误 按照我的理解,error_reporting(0)之后就应该不会显示错误了,这是怎么回事? 后来我又试着在php.ini者 ...

  10. 【学习笔记】QT常用类及应用

    一.QT基类: QObject 二.QT中常用的库 QT中的类根据功能划分在不同的库中,在用户属性.pro文件中可以看到. 三.Qt基本对话框的使用 常用5类: 通过类名可以直接调用类的静态成员函数. ...