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

  1. UVaLive 4452 The Ministers' Major Mess (TwoSat)

    题意:有 m 个人对 n 个方案投票,每个人最多只能对其中的4个方案投票(其他的相当于弃权),每一票要么支持要么反对.问是否存在一个最终决定,使得每个投票人都有超过一半的建议被采纳,在所有可能的最终决 ...

  2. uvalive 4452 The Ministers’ Major Mess

    题意: 有一些部长需要对某些账单进行投票. 一个部长最多对4个账单进行投票,且每票对一个账单通过,要么否决. 问是否存在一个方案使得所有部长有超过半数的投票被通过,如果有,那么说明哪些账单的决定是明确 ...

  3. UVALive-4452 The Ministers' Major Mess (2-SAT)

    题目大意:有n个问题,m个人来投票,没人最多投4票,问该怎样决定才能使每个人都有超过一半的票数被认可? 题目分析:2-SAT问题.如果某个人投的票数少于2,则这两票军被采纳,如果票数至少三票,则最多有 ...

  4. 【2-SAT】The Ministers’ Major Mess UVALive – 4452

    题目链接:https://cn.vjudge.net/contest/209474#problem/C 题目大意: 一共有m个提案,n个政客,每个政客都会对一些提案(最多四个)提出自己的意见——通过或 ...

  5. UVALive 5966 Blade and Sword -- 搜索(中等题)

    题意:给一幅地图,P为起点,D为终点,'*'为传送阵,到达传送阵可以传到任意一个其他的传送阵,传到以后可以正常走或者再传回来,问P->D最短步数. 分析:这题一定要细心,分析要到位才能搞定,错一 ...

  6. uva1086 The Ministers' Major Mess

    题意:有n 个议案,m 个大臣,每个大臣会对其中的ki 个议案投票,为赞成或反对.现要你判断是否存在一种方案,使得每个大臣有大于一半的投票被满足.若存在,还需判断某个议案是不是一定要通过,或者一定不能 ...

  7. 【UVALive - 3211】Now or later (二分+2-SAT)

    题意: 有n架飞机需要着陆.每架飞机有两种选择,早着陆或者晚着陆,二选其一.现在为了保证飞机的着陆安全,要求两架着陆的飞机的时间间隔的最小值达到最大. 分析: 最小值最大问题我们想到二分答案.对于猜测 ...

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

  9. 学习笔记(two sat)

    关于two sat算法 两篇很好的论文由对称性解2-SAT问题(伍昱), 赵爽 2-sat解法浅析(pdf). 一些题目的题解 poj 3207 poj 3678 poj 3683 poj 3648 ...

随机推荐

  1. vs2008调试提示:未安装Silverlight托管调试包

    换个启动浏览器,解决了. 右击项目,选择“属性”,选择"web";启动操作设置“启动外部程序”,填入浏览器exe的路径. 命令行参数填入地址.即可.

  2. HTML特殊转义字符对照表

    字符 十进制 转义字符 字符 十进制 转义字符 字符 十进制 转义字符 ? ¡ ¡ Á Á Á á á á ¢ ¢ ¢ Â Â ˆ â â £ £ £ Ã Ã Ã ã ã ã ¤ ¤ ¤ Ä Ä &a ...

  3. 【转】欧拉回路&特殊图下的哈密顿回路题集

    转自:http://blog.csdn.net/shahdza/article/details/7779385 欧拉回路[HDU]1878 欧拉回路 判断3018 Ant Trip 一笔画问题1116 ...

  4. HDOJ 3547 DIY Cube 解题报告

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3547 题目大意:求用$C$种颜色给立方体的8个顶点染色的本质不同的方法.两种方法本质不同即不能通过旋转 ...

  5. 【BZOJ】【1022】【SHOI2008】小约翰的游戏John

    博弈论 一看题,哇这不是Nim游戏么= =直接异或起来……啊咧怎么不对? 这道题是[Anti-Nim],普通的Nim是取走最后一个就赢,这题是取走最后一个输…… 做法参见 2009年贾志豪论文< ...

  6. GCC 静态库和动态库

    转自GCC 静态库和动态库 //hello.c #include void print_hello() { printf("HelloWorld "); } //main.c #i ...

  7. Unity3d开发wp8问题汇总

    原地址:http://blog.csdn.net/sunshine_1984/article/details/12849117 .wp8应用点击返回键没有响应将Unity3d导出wp8工程后,编译工程 ...

  8. linux源码阅读笔记 jmpi指令(转)

    jmpi是段间跳转指令,用于x86实模式下, 如:BOOTSEG = 0x0c70 jmpi    4, #BOOTSEG 假如当前段CS==00h,那么执行此指令后将跳转到段CS==0x0c70,当 ...

  9. C#中 ? 和?? 的用法

    C#中 ?? 和? 的意思 1.? 如果直接定义一个 值类型,给负值null:就会提示“无法将 Null转换成‘值类型(比如:int)’,因为他是一种不可为null的值 de类型” 例如 int in ...

  10. [PHP]如何在百度(BAE)和新浪(SAE)的云平台使用PHP连接MySQL并返回结果数据

    <?php $dbname = 'VnOTxPFWoxzUBLtrQCCg'; $host = getenv('HTTP_BAE_ENV_ADDR_SQL_IP'); $port = geten ...