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)的更多相关文章

  1. UVA 11294 - Wedding(Two-Set)

    UVA 11294 - Wedding 题目链接 题意:有n对夫妻,0号是公主.如今有一些通奸关系(男男,女女也是可能的)然后要求人分配在两側.夫妻不能坐同一側.而且公主对面一側不能有两个同奸的人,问 ...

  2. uva 509 RAID!(磁盘数据)

    来自 https://blog.csdn.net/su_cicada/article/details/80085318 习题4-7 RAID技术(RAID!, ACM/ICPC World Final ...

  3. UVA 11168 Airport(凸包+直线方程)

    题意:给你n[1,10000]个点,求出一条直线,让所有的点都在都在直线的一侧并且到直线的距离总和最小,输出最小平均值(最小值除以点数) 题解:根据题意可以知道任意角度画一条直线(所有点都在一边),然 ...

  4. UVA 11624 Fire!(广度优先搜索)

    题目大意:在一个N*M的迷宫内,J代表某人(只有一个),F代表火(可能不只一个),#代表墙,火每分钟会向四周除了墙以外的地方扩散一层,问人能否在没被火烧到 之前逃出迷宫,若能逃出输出最短时间.很明显的 ...

  5. UVA 11478 Halum(差分约束)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=34651 [思路] 差分约束系统. 设结点u上的操作和为sum[u] ...

  6. UVA 12263 Rankings(拓扑排序)

    给出一个n个数的序列1,然后有m个改动(a, b),在序列2中a跟b在序列中的相对顺序改变.求符合题意的序列2. 题中说道如果一个数的位置不确定,则输出‘?' ,仔细想想,这种情况是不会存在的,因为在 ...

  7. uva 10288 Coupons (分数模板)

    https://vjudge.net/problem/UVA-10288 大街上到处在卖彩票,一元钱一张.购买撕开它上面的锡箔,你会看到一个漂亮的图案. 图案有n种,如果你收集到所有n(n≤33)种彩 ...

  8. UVa 104 - Arbitrage(Floyd动态规划)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  9. 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 ...

随机推荐

  1. 1066: [SCOI2007]蜥蜴 - BZOJ

    Description 在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外. 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平 ...

  2. java mail实现Email的发送,完整代码

    java mail实现Email的发送,完整代码 1.对应用程序配置邮件会话 首先, 导入jar <dependencies> <dependency> <groupId ...

  3. cg 到hlsl的转换

    http://msdn.microsoft.com/en-us/library/windows/desktop/ff471376(v=vs.85).aspx http://gamedev.stacke ...

  4. Appium对京东App中WebView的处理

    Appium用uiautomator无法对WebView进行className定位,所以只能模拟动作.可以用android sdk自带的monitor工具,先进行截图,再用任意图像处理软件,获取截图的 ...

  5. 创建和编辑 crontab 文件

    http://docs.oracle.com/cd/E24847_01/html/819-6951/sysrescron-24589.html 创建和编辑 crontab 文件 创建 crontab  ...

  6. 【转载】关于ActionContext.getContext().getParameters()获值问题

    ActionContext.getContext().getParameters():一个学员问题的解答 2012-11-12 15:12:05|  分类: 默认分类 |  标签:struts2   ...

  7. 区间dp笔记√

    区间DP是一类在区间上进行dp的最优问题,一般是根据问题设出一个表示状态的dp,可以是二维的也可以是三维的,一般情况下为二维. 然后将问题划分成两个子问题,也就是一段区间分成左右两个区间,然后将左右两 ...

  8. ios APP屏幕快照尺寸

    苹果上传APP审核需要上传APP屏幕快照,分别有3.5寸,4寸,4.7寸,5.5寸,ipad五种图片,对应尺寸大小: 3.5寸:横坚屏 640*960 或960*640 4寸:横坚屏 640*1036 ...

  9. Callable与Future的简单介绍

    Callable与Future的介绍 Callable与 Future 两功能是Java在后续版本中为了适应多并法才加入的,Callable是类似于Runnable的接口,实现Callable接口的类 ...

  10. JavaWeb项目开发案例精粹-第3章在线考试系统-004Service层

    1. package com.sanqing.service; import java.util.List; import com.sanqing.po.Student; public interfa ...