POJ.3648.Wedding(2-SAT)
题意看这吧。。https://www.cnblogs.com/wenruo/p/5885948.html
\(Solution\)
每对夫妇只能有一个坐在新娘这一边,这正符合2-SAT初始状态
若以0表示新娘,以1表示新郎
那么对于有关系的u,v(i'表示在新娘一侧),应该连边u->v',v->u',而不是用i'表示新娘对面(新郎一侧),而连边u'->v,v'->u
因为如果新郎与v有关系,就会连边1(u')->v',这成了同在新郎一侧了;但若新娘与v有关系,连边0(u)->v'(同在新娘一侧)是符合连边规则的
有矛盾的情况是有关系的两人同在新娘对面,所以2-SAT求出的可行解是新娘对面的
新娘与新郎要坐在两侧,连边0->1,表示不能选0,一定选1,这样选出来的解就是新娘对面了
每对夫妇就是对立的,也不分性别。。所以随便一个表示i,另一个就表示i'
输出方案时只要输出与新娘染色相同的就可以了
是bel[i]还是i不要混 注意与新郎新娘标号统一
总是有点想不明白。。
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
const int N=5005,M=1e5+5;
int n,m,Enum,H[N],nxt[M],to[M],sk[N],top,cnt,bel[N],low[N],dfn[N],id;
int num,head[N],snxt[N],sto[N],conf[N],dgr[N]/*indgree*/,col[N],q[N];//conflict
bool ins[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int u,int v){
to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
inline void AddEdge2(int u,int v){
++dgr[v], sto[++num]=v, snxt[num]=head[u], head[u]=num;
}
void Tarjan(int x)
{
dfn[x]=low[x]=++id, sk[++top]=x, ins[x]=1;
for(int v,i=H[x]; i; i=nxt[i])
if(!dfn[v=to[i]]) Tarjan(v), low[x]=std::min(low[x],low[v]);
else if(ins[v]) low[x]=std::min(low[x],dfn[v]);
if(low[x]==dfn[x])
{
++cnt;
do{
bel[sk[top]]=cnt, ins[sk[top--]]=0;
}while(x!=sk[top+1]);
}
}
bool Topo()
{
for(int i=0; i<n<<1; i+=2)
if(bel[i]==bel[i^1]) return 0;
else conf[bel[i]]=bel[i^1],conf[bel[i^1]]=bel[i];
num=0, memset(head,0,sizeof head),
memset(col,0,sizeof col), memset(dgr,0,sizeof dgr);
for(int x=0; x<n<<1; ++x)
for(int i=H[x]; i; i=nxt[i])
if(bel[x]!=bel[to[i]]) AddEdge2(bel[to[i]],bel[x]);
int h=0,t=0;
for(int i=1; i<=cnt; ++i)
if(!dgr[i]) q[t++]=i;
while(h<t)
{
int x=q[h++];
if(!col[x]) col[x]=1,col[conf[x]]=2;
for(int i=head[x]; i; i=snxt[i])
if(!--dgr[sto[i]]) q[t++]=sto[i];
}
return 1;
}
int main()
{
while(n=read(),m=read(),n&&m)
{
id=top=cnt=Enum=0, memset(H,0,sizeof H);
memset(dfn,0,sizeof dfn);
char c,d; int a,b,s,t;
while(m--)
{
scanf("%d%c %d%c",&a,&c,&b,&d);
// s= c=='h'?a<<1:a<<1|1;//WA:这表示的man是2a,但是新郎也是man 是2a+1=1
s= c=='w'?a<<1:a<<1|1;
t= d=='w'?b<<1:b<<1|1;
AddEdge(s,t^1), AddEdge(t,s^1);
}
AddEdge(0,1);
for(int i=0; i<n<<1; ++i)
if(!dfn[i]) Tarjan(i);
if(Topo())
{
for(int i=1; i<n; ++i)
if(col[bel[i<<1]]==1) printf("%dh ",i);
else printf("%dw ",i);
putchar('\n');
}
else puts("bad luck");
}
return 0;
}
POJ.3648.Wedding(2-SAT)的更多相关文章
- POJ 3648 Wedding(2-SAT的模型运用+DFS | Tarjan)
Wedding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 10427 Accepted: 3170 Specia ...
- poj 3648 Wedding 2-SAT问题入门题目
Description Up to thirty couples will attend a wedding feast, at which they will be seated on either ...
- POJ 3648 Wedding (2-SAT,经典)
题意:新郎和新娘结婚,来了n-1对夫妻,这些夫妻包括新郎之间有通奸关系(包括男女,男男,女女),我们的目地是为了满足新娘,新娘对面不能坐着一对夫妻,也不能坐着有任何通奸关系的人,另外新郎一定要坐新娘对 ...
- POJ 3648 Wedding
2-SAT,直接选择新娘一侧的比较难做,所以处理的时候选择新郎一侧的,最后反着输出就可以. A和B通奸的话,就建边 A->B'以及B->A’,表示 A在新郎一侧的话,B一定不在:B在新郎一 ...
- POJ - 3648 Wedding (2-SAT 输出解决方案)
题意:有N-1对夫妇和1对新郎新娘要出席婚礼,这N对人要坐在走廊两侧.要求每对夫妇要坐在不同侧.有M对人有通奸关系,对于这一对人,不能同时坐在新娘对面(新娘新郎也可能和别人有通奸关系).求如何避免冲突 ...
- poj 3648 Wedding【2-SAT+tarjan+拓扑】
看错题*n,注意是输出新娘这边的-- 按2-SAT规则连互斥的边,然后注意连一条(1,1+n)表示新娘必选 然后输出color[belong[i]]==color[belong[1+n(新娘)]]的点 ...
- 【POJ】3648 Wedding
http://poj.org/problem?id=3648 题意:n对人(编号0-n-1,'w'表示第一个人,'h'表示第二个人),每对两个,人坐在桌子两侧.满足:1.每对人中的两个人不能坐在同一侧 ...
- Wedding (poj 3648 2-SAT 输出随意一组解)
Language: Default Wedding Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9004 Accept ...
- Map Labeler POJ - 2296(2 - sat 具体关系建边)
题意: 给出n个点 让求这n个点所能建成的正方形的最大边长,要求不覆盖,且这n个点在正方形上或下边的中点位置 解析: 当然是二分,但建图就有点还行..比较难想..行吧...我太垃圾... 2 - s ...
随机推荐
- linux新内核的freeze框架以及意义【转】
转自:https://blog.csdn.net/dog250/article/details/5303442 linux的电源管理发展非常迅速,比如在挂起到内存的时候,系统会冻结住所有的进程,也就是 ...
- centos环境自动化批量安装jdk软件脚本
自动化安装jdk软件部署脚本 准备工作: 1.在执行脚本的服务器上生成免密码公钥: 安装expect命令 yum install -y expect ssh-keygen 三次回车 2.将jdk-7u ...
- Python-浮动 清浮动
# 浮动布局 ## 一.display总结 ```css/* inline *//*1.同行显示, 就相当于纯文本, 当一行显示不下, 如就是一个字显示不下,那么显示不下的那一个字就会自动换行,和纯文 ...
- keras2.0的一些变化
keras 变化太快了https://github.com/fchollet/keras/wiki/Keras-2.0-release-notes
- C++ code:位操作实例(bit operation example)
某任务需要在A.B.C.D.E这五个人中物色人员去完成,但派人受限于下列条件: (1)若A去,则B跟去 (2)D,E两人中必有人去 (3)B,C两人中必有人去,但只去一人 (4)C,D两人要么都去,要 ...
- poj3264 倍增法(ST表)裸题
打出st表的步骤:1:建立初始状态,2:区间按2的幂从小到大求出值 3:查询时按块查找即可 #include<iostream> #include<cstring> #incl ...
- 性能测试十三:linux常用命令
常用的linux命令: 目录类/ 根目录. 当前目录.. 上级目录cd / 进入根目录cd .. 进入上级目录ls 查看当前目录下的所有文件ll 查看当前目录下所有文件的详细信息pwd 显示当前目录的 ...
- Redis、RabbitMQ、Memcached
知识目录: Memcached Redis RabbitMQ Memcached 回到顶部 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中 ...
- POJ 2752 Seek the Name, Seek the Fame(next数组运用)
Seek the Name, Seek the Fame Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24000 ...
- 在.NET环境下使用KAFKA
近日基于项目的解耦与削峰需求,决定在项目中引入消息队列.因为同时项目部分业务已经迁移到Java上,所以消息队列组件又要兼顾Java环境下的使用,选来选去对比了RabbitMQ.RocketMQ和Kaf ...