poj 3648 2-SAT问题
思路:将每对夫妻看成是对立状态,每个不正常关系都是一个矛盾,按2-SAT的方式建边。最后建一条新娘到新郎的边。具体看注释
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define Maxn 62
#define Maxm Maxn*Maxn
using namespace std;
int vi[Maxn],head[Maxn],dfn[Maxn],low[Maxn],e,n,lab,top,num,id[Maxn],Stack[Maxn],in[Maxn],Hash[Maxn],col[Maxn];
struct Edge{
int u,v,next;
}edge[Maxm];
void init()//初始化
{
memset(vi,,sizeof(vi));
memset(head,-,sizeof(head));
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(id,,sizeof(id));
memset(in,,sizeof(in));
memset(col,,sizeof(col));
e=lab=top=num=;
}
void add(int u,int v)//加边
{
edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
}
void Tarjan(int u)//找出强连通分支
{
int i,j,v;
dfn[u]=low[u]=++lab;
Stack[top++]=u;
vi[u]=;
for(i=head[u];i!=-;i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v])
{
Tarjan(v);
low[u]=min(low[u],low[v]);
}
if(vi[v])
low[u]=min(low[u],dfn[v]); }
if(low[u]==dfn[u])
{
++num;
do{
i=Stack[--top];
vi[i]=;
id[i]=num;
}while(i!=u);
}
}
void buildGraphic()//缩点后重新建树,以便进行拓扑排序
{
int ed=e,u,v;
memset(head,-,sizeof(head));
e=;
int i;
for(i=;i<ed;i++)
{
u=edge[i].u;
v=edge[i].v;
if(id[u]!=id[v])
{
add(id[v],id[u]);//由于2-SAT问题中是找出度为0的点,这里我们建个反图,方便进行拓扑排序,变成找入度为0的点
in[id[u]]++;
}
}
}
void Topsort()
{
int i,j,u,v,temp;
queue<int> q;
int fron,rear;
fron=rear=;
for(i=;i<=num;i++)
if(in[i]==)
q.push(i);
while(!q.empty())
{
temp=q.front();
q.pop();
if(!col[temp]) col[temp]=,col[Hash[temp]]=;//如果该连通分支未着色,那么给他着1,它的对立点就必须着不同的色
for(i=head[temp];i!=-;i=edge[i].next)
{
v=edge[i].v;
in[v]--;
if(in[v]==)
q.push(v);
}
}
}
int solve()
{
int i,j;
for(i=;i<=*n;i++)
if(!dfn[i])
Tarjan(i);
for(i=;i<=n;i++)
if(id[i]==id[i+n])
return ;//有矛盾则结束
else
Hash[id[i]]=id[i+n],Hash[id[i+n]]=id[i];//标记每个连通分支间的对立关系,即不能再同一侧 buildGraphic();
Topsort();
for(i=;i<=n;i++)
if(col[id[i]]==col[id[n+]]) printf("%dh ",i-);//输出和新娘同侧的人
else printf("%dw ",i-);
printf("\n");
return ;
}
int op(int x)
{
if(x<=n) return x+n;
return x-n;
}
int main()
{
int m,i,j,a,b;
char c1,c2;
while(scanf("%d%d",&n,&m),n|m)
{
init();
for(i=;i<m;i++)
{
scanf("%d%c%d%c",&a,&c1,&b,&c2);//husband点为1~N,wife点为N+1~2*N
a++,b++;
if(c1=='w')
a+=n;
if(c2=='w')
b+=n;
add(a,op(b));
add(b,op(a));
}//我们的目标是选择和新郎同一侧的,新郎固然在自己一侧。
add(n+,);//建一条由新娘到新郎的边,若选择了新娘,新郎也会被选,新郎和新娘成了同侧,便矛盾。即新娘不能和新郎同一侧
if(!solve())
printf("bad luck\n");
}
return ;
}
poj 3648 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 2-sat
题目大意: 有一对新人结婚,邀请n对夫妇去参加婚礼. 有一张很长的桌子,人只能坐在桌子的两边,还要满 足下面的要求:1.每对夫妇不能坐在同一侧 2.n对夫妇 之中可能有通奸关系(包括男男,男女,女女) ...
- POJ 3648 Wedding (2-SAT,经典)
题意:新郎和新娘结婚,来了n-1对夫妻,这些夫妻包括新郎之间有通奸关系(包括男女,男男,女女),我们的目地是为了满足新娘,新娘对面不能坐着一对夫妻,也不能坐着有任何通奸关系的人,另外新郎一定要坐新娘对 ...
- poj 1687 Buggy Sat 简单计算几何
暑期集训出的第一道一血 感觉自己萌萌哒…… 这道题本身并没有坑点 仅仅是翻译巨坑…… 解大腿在做B 安学长在做E 我闲着也没事 就一个词一个词翻译F…… 最后感觉…… 题干大多数都看不懂…… 也都没啥 ...
- POJ 3648 Wedding
2-SAT,直接选择新娘一侧的比较难做,所以处理的时候选择新郎一侧的,最后反着输出就可以. A和B通奸的话,就建边 A->B'以及B->A’,表示 A在新郎一侧的话,B一定不在:B在新郎一 ...
- poj 3648 2-SAT建图+topsort输出结果
其实2-SAT类型题目的类型比较明确,基本模型差不多是对于n组对称的点,通过给出的限制条件建图连边,然后通过缩点和判断冲突来解决问题.要注意的是在topsort输出结果的时候,缩点后建图需要反向连边, ...
- POJ.3648.Wedding(2-SAT)
题目链接 题意看这吧..https://www.cnblogs.com/wenruo/p/5885948.html \(Solution\) 每对夫妇只能有一个坐在新娘这一边,这正符合2-SAT初始状 ...
- POJ - 3648 Wedding (2-SAT 输出解决方案)
题意:有N-1对夫妇和1对新郎新娘要出席婚礼,这N对人要坐在走廊两侧.要求每对夫妇要坐在不同侧.有M对人有通奸关系,对于这一对人,不能同时坐在新娘对面(新娘新郎也可能和别人有通奸关系).求如何避免冲突 ...
随机推荐
- JDBC学习笔记(6)——获取自动生成的主键值&处理Blob&数据库事务处理
获取数据库自动生成的主键 [孤立的技术是没有价值的],我们这里只是为了了解具体的实现步骤:我们在插入数据的时候,经常会需要获取我们插入的这一行数据对应的主键值. 具体的代码实现: /** * 获取数据 ...
- POJ 3667 Hotel (线段树区间合并)
题目链接:http://poj.org/problem?id=3667 最初给你n间空房,m个操作: 操作1 a 表示检查是否有连续的a间空房,输出最左边的空房编号,并入住a间房间. 操作2 a b ...
- SQL 错误1418
1.一个或多个服务器网络地址缺少完全限定域名(FQDN).为每个服务器指定FQDN,然后再次单击“开始镜像”.2.服务器网络地址"TCP://primary.test.com:5022&qu ...
- disque概要
做项目过程接触到disque,记录一下. disque是redis之父开源的基于内存的分布式作业队列,用c语言实现的非阻塞网络服务器. disque的设计目标:Its goal is to captu ...
- Oracle-11g 数据库启动时,报错"ORA-01092"及"ORA-18008: cannot find OUTLN schema"
适用情形: Oracle-11g 数据库启动时,出现类似如下错误. ORA-01092: ORACLE instance terminated. Disconnection forced ORA-18 ...
- 定义member【C++】cstddef中4个定义
最近研究定义member,稍微总结一下,以后继续补充: size_t size_t corresponds to the integral data type returned by the lang ...
- 记录一下跟Python有关的几个拓展名
.py python文本源码文件,也可以用python.exe直接运行 .pyw 也是python的文本源码文件,但是默认由pythonw.exe打开,而且不显示命令行窗口,带GUI的python代码 ...
- java 覆盖hashCode()深入探讨 代码演示样例
java 翻盖hashCode()深入探讨 代码演示样例 package org.rui.collection2.hashcode; /** * 覆盖hashcode * 设计HashCode时最重要 ...
- SAP BW 平面文件创建信息立方体
T-CODE:RSA1 1.创建信息范围 2.创建信息范围 创建特性信息对象目录 创建关键指标信息对象目录 3.创建特性信息对象 依次创建客户,销售组织 4.创建关键指标 依次创建单价和金额 5.创建 ...
- PAT 1004
1004. Counting Leaves (30) A family hierarchy is usually presented by a pedigree tree. Your job is t ...