UVA 11294 Wedding(2-sat)
2-sat。不错的一道题,学到了不少。
需要注意这么几点:
1、题目中描述的是有n对夫妇,其中(n-1)对是来为余下的一对办婚礼的,所以新娘只有一位。
2、2-sat问题是根据必然性建边,比如说A与B二选一,那么当不选A时,必然选B。在本题中,我们所能确定的必然性只有一种:当一对通奸者中的一个人出现在新娘的对面时,另一个必须在新娘的同侧。一开始,我每次建的是两条边,即由新娘指向对面的一人,再从这个人,指向与新娘同侧的另一人(语言描述较困难,但我尽量简明的表达出来)。这是一种假设,因为新娘既可能在左边,又可能在右边。但是这不是必然性:“新娘指向对面的一个人”,这条边不存在必然关系。
解决办法:我们假定新娘就在某一侧。那么是否会影响最终结果呢?不会,因为不管在那一侧,只要有正确方案,转换一下方向,总归是成立的。
3、如何确定新娘就在某一侧?
建边的过程,我们假定了新娘的位置,但是并没有确定的在程序中表现出,新娘就在这一侧。
方法:(1)mark[0]=1;明确的表示出新娘已被标记,但需要注意的是,每次dfs标记的是一条链,或者说是以你选择的点为根的一棵树,所以,只是这样做是不够的,需要单独对mark[0]做一次dfs。
(2)如代码中写的,dfs过程中,若是在 dfs(0) 时失败了,那么就return false;不给 dfs(1) 机会。
注意:准确的说,确定了新娘的位置,即确定了“0w”和“0h”的位置,那么所有包含“0w”或“0h”的关系,所建的边都只能有一条。不过删掉约束条件一样能ac,仔细想来,是solve()中if(i==0)return false;的功劳,因为我只允许dfs(0)成功,所以即使建了另一条边,也不会有机会搜的。
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<algorithm>
using namespace std; const int MAXN=; int n;
bool mark[MAXN<<];
int S[MAXN<<],c;
vector<int >G[MAXN<<]; void init(int n)
{
for(int i=;i<(n<<);i++)
G[i].clear();
memset(mark,,sizeof(mark));
} void add(int x,int xval,int y,int yval)
{
x=(x<<)+xval;
y=(y<<)+yval;
G[x].push_back(y);
} bool dfs(int x)
{
if(mark[x^]){
return false;
}
if(mark[x]){
return true;
}
S[c++]=x;
mark[x]=true;
for(int i=;i<G[x].size();i++)
{
if(!dfs(G[x][i])){
return false;
}
}
return true;
} bool solve()
{
for(int i=;i<(n<<);i+=)
{
if(!mark[i]&&!mark[i+]){
c=;
if(!dfs(i)){
if(i==) //如果新娘在 0 这一侧这一前提不成立,则 no solusion
return false;
while(c>)
mark[S[--c]]=false;
if(!dfs(i+))
return false;
}
}
}
return true;
} int main()
{
int m,a,b;
char x,y;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m)
return ; init(n);
for(int i=;i<m;i++) //固定新娘在 0 这一侧
{
scanf("%d%c %d%c",&a,&x,&b,&y);
if(x=='h'&&y=='h'){
add(a,,b,);
add(b,,a,);
}else if(x=='w'&&y=='w'){
add(a,,b,);
add(b,,a,);
}else if(x=='h'&&y=='w'){
add(a,,b,);
add(b,,a,);
}else if(x=='w'&&y=='h'){
add(a,,b,);
add(b,,a,);
}
} if(solve()){
for(int i=;i<n;i++)
{
if(mark[i<<])
printf("%dw",i);
else
printf("%dh",i);
if(i!=n-)
printf(" ");
}
printf("\n");
}else
printf("bad luck\n");
}
return ;
}
/*
附上一组数据,让我发现了第三个问题
10 10
6h 2w
1h 9w
1w 3w
9w 0h
1h 9h
4h 1w
7h 2w
1h 0h
0h 9w
0h 3h
*/
UVA 11294 Wedding(2-sat)的更多相关文章
- UVA 11294 - Wedding(Two-Set)
UVA 11294 - Wedding 题目链接 题意:有n对夫妻,0号是公主.如今有一些通奸关系(男男,女女也是可能的)然后要求人分配在两側.夫妻不能坐同一側.而且公主对面一側不能有两个同奸的人,问 ...
- uva 509 RAID!(磁盘数据)
来自 https://blog.csdn.net/su_cicada/article/details/80085318 习题4-7 RAID技术(RAID!, ACM/ICPC World Final ...
- UVA 11168 Airport(凸包+直线方程)
题意:给你n[1,10000]个点,求出一条直线,让所有的点都在都在直线的一侧并且到直线的距离总和最小,输出最小平均值(最小值除以点数) 题解:根据题意可以知道任意角度画一条直线(所有点都在一边),然 ...
- UVA 11624 Fire!(广度优先搜索)
题目大意:在一个N*M的迷宫内,J代表某人(只有一个),F代表火(可能不只一个),#代表墙,火每分钟会向四周除了墙以外的地方扩散一层,问人能否在没被火烧到 之前逃出迷宫,若能逃出输出最短时间.很明显的 ...
- UVA 11478 Halum(差分约束)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651 [思路] 差分约束系统. 设结点u上的操作和为sum[u] ...
- UVA 12263 Rankings(拓扑排序)
给出一个n个数的序列1,然后有m个改动(a, b),在序列2中a跟b在序列中的相对顺序改变.求符合题意的序列2. 题中说道如果一个数的位置不确定,则输出‘?' ,仔细想想,这种情况是不会存在的,因为在 ...
- uva 10288 Coupons (分数模板)
https://vjudge.net/problem/UVA-10288 大街上到处在卖彩票,一元钱一张.购买撕开它上面的锡箔,你会看到一个漂亮的图案. 图案有n种,如果你收集到所有n(n≤33)种彩 ...
- UVa 104 - Arbitrage(Floyd动态规划)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
- POJ 3678 Katu Puzzle(2 - SAT) - from lanshui_Yang
Description Katu Puzzle is presented as a directed graph G(V, E) with each edge e(a, b) labeled by a ...
随机推荐
- HDU 1423 Greatest Common Increasing Subsequence LCIS
题目链接: 题目 Greatest Common Increasing Subsequence Time Limit: 2000/1000 MS (Java/Others) Memory Limit: ...
- JS中删除字符串中的空格
问题描述: 在进行字符串操作时,由于字符串中存在较多的空格,因此需要考虑取消字符串中的空格 问题解决: (1)删除字符串中的前导空格(字符串的前面的空格): 注意:这里使用 ...
- Matlab中find函数的使用
一.问题来源 看到了 min_score_pos = find(A0_scores==min(A0_scores), 1); [r,c] = find(X,k),返回X中第k个非零元素的行列位置. 二 ...
- [设计模式] 14 命令模式 Command
Command 模式通过将请求封装到一个对象(Command)中,并将请求的接受者存放到具体的 ConcreteCommand 类中(Receiver)中,从而实现调用操作的对象和操作的具体实现者之间 ...
- 设置Eclipse智能提示
原地址:http://blog.csdn.net/sz_bdqn/article/details/4956162 今天有点时间,研究了一下MyEclispse的智能感知的功能.刚开始使用它时总是感觉如 ...
- override equals in Java
equals() (javadoc) must define an equality relation (it must be reflexive, symmetric, and transitive ...
- HDU 2473 Junk-Mail Filter(并查集+删点,设立虚父节点/找个代理)
题意:有N封邮件, 然后又两种操作,如果是M X Y , 表示X和Y是相同的邮件.如果是S X,那么表示对X的判断是错误的,X是不属于X当前所在的那个集合,要把X分离出来,让X变成单独的一个.最后问集 ...
- 桥接模式(Bridge Pattern)
1,定义 桥接模式(Bridge Pattern),也称为桥梁模式,其用意是将抽象化与实现化脱耦,使得两者可以独立的变化,它可以使软件系统沿着多个方向进行变化,而又不引入额外的复杂 ...
- [Ruby on Rails系列]6、一个简单的暗语生成器与解释器(上)
[0]Ruby on Rails 系列回顾 [Ruby on Rails系列]1.开发环境准备:Vmware和Linux的安装 [Ruby on Rails系列]2.开发环境准备:Ruby on Ra ...
- lintcode:子数组之和为0
题目: 子数组之和 给定一个整数数组,找到和为零的子数组.你的代码应该返回满足要求的子数组的起始位置和结束位置 样例 给出[-3, 1, 2, -3, 4],返回[0, 2] 或者 [1, 3]. 解 ...