UVALive 4452 The Ministers' Major Mess(2-sat)
2-sat。又学到了一种使用的方法:当确定选择某中状态A时,从它的对立状态A^1引一条边add(A^1,A),从而使凡是dfs经过对立状态,必然return false;即保证若存在一种可能性,必然是经过该状态A的。
题意:m个人对n个方案投票,每人之多投4票,是否存在一种方案使每个人所投的一半以上的票被采纳。依次输出每个议题最终的结果。
1、注意是一半以上,我一开始理解成一半,结果无法根据必然性建边。<=2票则都被采纳,<=4票则至多有一票不被采纳。
2、输出时要注意,因为每个议题的结果都不一定相同,所以需要一一判断。需要分别进行solve(i),和solve(i+1)。这里一开始我直接是把solve()函数中的dfs(i)和dfs(i+1)分开,wa了,后来考虑发现,solve()一次,是对遍历整个方案寻找可行性;而dfs()只是对一个连通的量做了标记。
注意:分别检查同一个议题的两种状态,确定从状态A经过,add(A^1,A),结束要记得G[i].pop_back();
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
using namespace std; const int MAXN=; struct Vote{
int v,c;
}vote[MAXN][]; bool mark[MAXN<<];
int res[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 dx,int y,int dy)
{
x=(x<<)+dx;
y=(y<<)+dy;
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(int n)
{
for(int i=;i<(n<<);i+=)
{
if(!mark[i]&&!mark[i+]){
c=;
if(!dfs(i)){
while(c>)
mark[s[--c]]=false;
if(!dfs(i+))
return false;
}
}
}
return true;
} bool test(int n)
{
for(int i=;i<n;i++)
{
int ans=;
memset(mark,,sizeof(mark));
add(i,,i,);
while(c>)
mark[s[--c]]=false;
if(solve(n))
ans+=;
G[(i<<)+].pop_back(); memset(mark,,sizeof(mark));
add(i,,i,);
while(c>)
mark[s[--c]]=false;
if(solve(n))
ans+=;
G[i*].pop_back(); if(ans==)
return false;
else if(ans==)
res[i]=-;
else if(ans==)
res[i]=;
else if(ans==)
res[i]=;
}
return true;
} int main()
{
int n,m;
int cnt=,ans;
while(~scanf("%d%d",&n,&m))
{
if(!n&&!m)
return ; init(n); //!!
for(int i=;i<m;i++)
{
scanf("%d",&ans); for(int j=;j<ans;j++)
{
int x;
char ch[];
scanf("%d %s",&x,ch);
vote[i][j].v=--x;
if(ch[]=='y')
vote[i][j].c=;
else
vote[i][j].c=;
}
if(ans<=){
for(int j=;j<ans;j++)
add(vote[i][j].v,vote[i][j].c^,vote[i][j].v,vote[i][j].c);
}else
for(int j=;j<ans;j++)
for(int k=;k<ans;k++)
{
if(j==k)
continue;
add(vote[i][j].v,vote[i][j].c^,vote[i][k].v,vote[i][k].c);
}
} memset(res,,sizeof(res));
printf("Case %d: ",++cnt);
if(!test(n))
printf("impossible\n");
else {
for(int i=;i<n;i++)
{
if(res[i]==)
printf("?");
else if(res[i]==)
printf("y");
else if(res[i]==-)
printf("n");
}
printf("\n");
}
}
return ;
}
/*
5 3
2 1 y 2 n
3 1 y 3 n 4 y
4 1 n 3 n 4 n 5 y
*/
UVALive 4452 The Ministers' Major Mess(2-sat)的更多相关文章
- UVaLive 4452 The Ministers' Major Mess (TwoSat)
题意:有 m 个人对 n 个方案投票,每个人最多只能对其中的4个方案投票(其他的相当于弃权),每一票要么支持要么反对.问是否存在一个最终决定,使得每个投票人都有超过一半的建议被采纳,在所有可能的最终决 ...
- uvalive 4452 The Ministers’ Major Mess
题意: 有一些部长需要对某些账单进行投票. 一个部长最多对4个账单进行投票,且每票对一个账单通过,要么否决. 问是否存在一个方案使得所有部长有超过半数的投票被通过,如果有,那么说明哪些账单的决定是明确 ...
- UVALive-4452 The Ministers' Major Mess (2-SAT)
题目大意:有n个问题,m个人来投票,没人最多投4票,问该怎样决定才能使每个人都有超过一半的票数被认可? 题目分析:2-SAT问题.如果某个人投的票数少于2,则这两票军被采纳,如果票数至少三票,则最多有 ...
- 【2-SAT】The Ministers’ Major Mess UVALive – 4452
题目链接:https://cn.vjudge.net/contest/209474#problem/C 题目大意: 一共有m个提案,n个政客,每个政客都会对一些提案(最多四个)提出自己的意见——通过或 ...
- UVALive 5966 Blade and Sword -- 搜索(中等题)
题意:给一幅地图,P为起点,D为终点,'*'为传送阵,到达传送阵可以传到任意一个其他的传送阵,传到以后可以正常走或者再传回来,问P->D最短步数. 分析:这题一定要细心,分析要到位才能搞定,错一 ...
- uva1086 The Ministers' Major Mess
题意:有n 个议案,m 个大臣,每个大臣会对其中的ki 个议案投票,为赞成或反对.现要你判断是否存在一种方案,使得每个大臣有大于一半的投票被满足.若存在,还需判断某个议案是不是一定要通过,或者一定不能 ...
- 【UVALive - 3211】Now or later (二分+2-SAT)
题意: 有n架飞机需要着陆.每架飞机有两种选择,早着陆或者晚着陆,二选其一.现在为了保证飞机的着陆安全,要求两架着陆的飞机的时间间隔的最小值达到最大. 分析: 最小值最大问题我们想到二分答案.对于猜测 ...
- 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 ...
- 学习笔记(two sat)
关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...
随机推荐
- mysql安装篇
装了vps,环境又要自己配置.mysql比较难装上. 1.安装MySQL 5.5.x的yum源:rpm -Uvh http://repo.webtatic.com/yum/centos/5/lates ...
- hibernate中文乱码问题
在学习hibernate的过程中,发现在往mysql数据库中插入数据的时候会报错. <property name="hibernate.connection.url"> ...
- 解决Maven默认仓库没有的jar下载(二)
前言: 在 “解决Maven不能下载“oracle.aspectjweaver.com.springsource.net.sf.cglib”jar(http://www.cnblogs.com/wql ...
- 母函数入门笔记(施工中…
定义:对于一个数列,它的母函数(即生成函数)为 为了对这个准确求值,我们设 举一个简单的例子 例1 对于数列 他的生成函数为 ,那么应用一下等比数列求和公式 这里由于 所以当时 那么 例 ...
- 将Windows上的文件上传到Linux上
下载一个SSH Secure Shell Client即可. SSHSecureShellClient-3.2.9下载地址: 免费下载地址在 http://linux.linuxidc.com/ 用户 ...
- 解决ubuntu中zip解压的中文乱码问题
转自解决ubuntu中zip解压的中文乱码问题 在我的ubuntu12.10中,发现显示中文基本都是正常的,只有在解压windows传过来的zip文件时,才会出现乱码.所以,我用另一个方法解决中文乱码 ...
- spring mvc 注解 annot失效
如果带上事务,那么用annotation方式的事务注解和bean配置,事务会失效,要将service bean配置到xml文件中才行 这个问题是由于问答上有解决方案 引用 这个问题很经典了 在主容器中 ...
- <%@page include%>、<%@include%>、<jsp:include>三者之间的本质区别
<%@page include%>.<%@include%>.<jsp:include>三者之间的本质区别 先从它的几个内置对象说起. application和se ...
- 2013山东省ICPC结题报告
A.Rescue The Princess 已知一个等边三角形的两个顶点A.B,求第三个顶点C,A.B.C成逆时针方向. 常规的解题思路就是用已知的两个点列出x,y方程,但这样求出方程的解的表达式比较 ...
- POJ 1191 棋盘分割(DP)
题目链接 题意 : 中文题不详述. 思路 : 黑书上116页讲的很详细.不过你需要在之前预处理一下面积,那样的话之后列式子比较方便一些. 先把均方差那个公式变形, 另X表示x的平均值,两边平方得 平均 ...