HDU1814(Peaceful Commission) 【2-SAT DFS暴力求最小字典序的模板】
题目链接: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暴力求最小字典序的模板】的更多相关文章
- Codeforces 959 树构造 暴力求最小字典序互质序列
A B C 题目给你一个结论 最少需要min((odd,even)个结点可以把一棵树的全部边连起来 要求你输出两颗树 一棵树结论是正确的 另外一棵结论是正确的 正确结论的树很好造 主要是错误的树 题目 ...
- hdu1814 Peaceful Commission
hdu1814 Peaceful Commission 题意:2-sat裸题,打印字典序最小的 我写了三个 染色做法,正解 scc做法,不管字典序 scc做法,错误的字典序贪心 #include &l ...
- HDU1814 Peaceful Commission 2-sat
原文链接http://www.cnblogs.com/zhouzhendong/p/8099115.html 题目传送门 - HDU1814 题面 Description 根据宪法,Byteland民 ...
- HDU-1814 Peaceful Commission 2sat
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1814 简单的2sat题. //STATUS:C++_AC_390MS_996KB #include & ...
- hdu1814 Peaceful Commission,2-sat
题目大意:一国有n个党派.每一个党派在议会中都有2个代表,现要组建和平委员会,要从每一个党派在议会的代表中选出1人,一共n人组成和平委员会.已知有一些代表之间存在仇恨,也就是说他们不能同一时候被选为和 ...
- hdu1814 Peaceful Commission——2-SAT
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1814 第一次的2-SAT,推荐博客:https://blog.csdn.net/jarjingx/arti ...
- poj 3009 冰球 【DFS】求最小步数
题目链接:https://vjudge.net/problem/POJ-3009 转载于:https://www.cnblogs.com/Ash-ly/p/5728439.html 题目大意: 要求把 ...
- poj1509(环形字符串求最小字典序)
题意:给你一串字符串,但是这串字符串是环形的,让你找个位置切开,使得它的字典序最小....... 思路:典型的最小表示法....... #include<iostream> #includ ...
- BZOJ4974(给Next求最小字典序原串)
输入给出了最小循环节长度,暗示next数组. 然后自己按照自己的kmp板子逆着来一遍就好. ; int n, a, Next[maxn]; char str[maxn]; ]; int main() ...
随机推荐
- C++自定义方法类、调用
如求矩形.圆的面积的方法,可以写成一个area类 area.h中只声明,不实现: #ifndef AREA_H //防止重复引用 #define AREA_H class area{//自定义类 pu ...
- Codevs 1298 凸包周长
1298 凸包周长 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 给出平面上n个点,求出这n个点形成的凸包的周长. 凸包的定 ...
- 【sed】基本用法
1. 文本处理 sed编辑器根据sed命令处理数据流中的数据:在流编辑器将所有命令与一行数据匹配完后,它会读取下一行数据并重复以下过程: (1) 一次从输入中读取一行数据 (2) 根据所提供的编辑器命 ...
- 黑马vue---17、vue中通过属性绑定绑定style行内样式
黑马vue---17.vue中通过属性绑定绑定style行内样式 一.总结 一句话总结: 如果属性名中带有短线必须加引号,比如: h1StyleObj: { color: 'red', 'font-s ...
- Android跨进程通信访问其他应用程序的Activity
访问其他应用程序的ActivityActivity既可以在进程内(同一个应用程序)访问,也可以跨进程访问.如果想在同一个应用程序中访问Activity,需要指定Context对象和Activity的C ...
- 如何快速查找到HTML头尾对应标签?
在使用Atom编辑器整理HTML代码的时候,希望快速找到HTML头尾对应的标签. ctrl+m 试试看
- Handler处理消息
UI主线程通过Looper循环查询消息队列UI_MQ,当发现有消息存在时会将消息从消息队列中取出.首先分析消息,通过消息的参数判断该消息对应的Handler,然后将消息分发到指定的Handler进行处 ...
- MySql锁和事务隔离级别
在讲mysql事物隔离级别之前,我们先简单说说mysql的锁和事务. 一:数据库锁 因为数据库要解决并发控制问题.在同一时刻,可能会有多个客户端对同一张表进行操作,比如有的在读取该行数据,其他的尝试去 ...
- python之scrapy模块scrapy-redis使用
1.redis的使用,自己可以多学习下,个人也是在学习 https://www.cnblogs.com/ywjfx/p/10262662.html官网可以自己搜索下. 2.下载安装scrapy-red ...
- xcode 老项目library not found for -libstdc++.6.0.9
Xcode升级到Xcode10.0后,由于去掉陈旧的libstdc++库替换为libc++,libc++相对是苹果最新版的C++库,经过优化并全面支持C++11 下载libstdc++库,链接: ht ...