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统计某个特定文件名的大小总和【原创】
[hch@EAISRVBJ2 log]$find ./ -name "test_chs_00*"|xargs du -ck|grep total|awk 'BEGIN{sum=0} ...
- asp.net动态解析用户控件(UserControl)
模块化的时候需要用到: #region asp.net解析用户控件 /// <summary> /// asp.net 解析用户控件 /// </summary> /// &l ...
- Ex 6_12 凸多边形的最优三角剖分..._第六次作业
假设顶点的总数为n,从0到n-1. 从序号为0的顶点开始以逆时针方向排序,对于 令子问题A[i,j]为包含顶点i,i+1, . . . j的凸多边形的最小三角剖分代价,dist(i,j)为顶点i到顶点 ...
- Android app 在线更新那点事儿(适配Android6.0、7.0、8.0)
一.前言 app在线更新是一个比较常见需求,新版本发布时,用户进入我们的app,就会弹出更新提示框,第一时间更新新版本app.在线更新分为以下几个步骤: 1, 通过接口获取线上版本号,versionC ...
- Storm的部署
配置方案如下 node1 Nimbus zookeeper node2 Supervisor zookeeper node3 Supervisor zookeeper node4 Supervisor ...
- Laravel Blade 模板 @section/endsection 与 @section/show, @yield 的区别
base layout 中需要使用 @section("section_name") 区块链是什么? @show 继承的 blade 中需要使用 @section("se ...
- JQuery中jsCharts图表插件(十)
一:1.jsCharts图表插件 注意:从官方下来的例子都没指定页面编码,在这种情况下,浏览器就会使用默认设置中文编码:GB2312,GBK等:导致无法执行. 请在html代码中的<head&g ...
- 云平台Linux主机安装流程
==一.安装包===================================================================================如果是1+2主机安装 ...
- poj 1631 最多能有多少条不交叉的线 最大非降子序列 (LIS)
左边的数字是1 2 3 4 5.... 右边的数字 第一个输入的和1连 第2个输入的和2连 右边再按从小到大排序 要求连线不能交叉 问最多能有多少条不交叉的线 假如右边有5个1 那么答案会是5 所以是 ...
- Lemur编写索引器
http://blog.sciencenet.cn/blog-273829-312138.html http://sourceforge.net/p/lemur/wiki/Home/ http://q ...