题意:

有一些部长需要对某些账单进行投票。

一个部长最多对4个账单进行投票,且每票对一个账单通过,要么否决。

问是否存在一个方案使得所有部长有超过半数的投票被通过,如果有,那么说明哪些账单的决定是明确的,哪些是不明确的;否则说明不可能。

思路:

2-SAT。

一开始觉得这是一个k-SAT问题,但是因为有着所有部长的投票有超过半数被通过这个条件存在,所以可以简化。

对于一票或者两票的部长,那么所有条件都要被满足,意味着某些账单的决定是确定。

如何表示一个条件是确定的呢,这是从这个题中学习到的一点,不是简单的标记这个条件的真假,而是从自己向自己的对立面连边,如果在搜索的过程中,发现自己和自己的对立面均被标记,那么就产生矛盾从而不满足条件了。

然后是对于3票或者4票的部长,要超过一半,如果一旦一个账单取相反的决定,那么其它账单都要取与输入相同的决定才能保证查过一半,再根据这个条件连边。

之后再解决如何确定一个账单的决定是否明确,对于一个账单,如果标记为通过能找到方案,否决也能找到方案,那么这个账单的决定就是不明确的,否则就可以判断其是明确的。在每一次标记了一个条件进行搜索之后,都必须将这个过程中标记过的点全部初始化,才能保证下一次搜索的正确。

代码:

 #include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std; const int maxn = ; struct twosat
{
int n;
vector<int> g[maxn*];
bool mark[maxn*];
int s[maxn*],c;
int ty[maxn]; bool dfs(int x)
{
if (mark[x^]) return false;
if (mark[x]) return true; mark[x] = true; s[c++] = x; for (int i = ;i < g[x].size();i++)
{
if (!dfs(g[x][i])) return false;
} return true;
} void add_clause(int x,int xval,int y,int yval)
{
x = x * + xval;
y = y * + yval; g[x^].push_back(y);
} void init(int n)
{
this -> n = n;
memset(mark,,sizeof(mark));
memset(ty,,sizeof(ty));
for (int i = ;i <= n * ;i++) g[i].clear();
} bool solve()
{
for (int i = ;i < n * ;i += )
{
if (!mark[i] && !mark[i+])
{
c = ; if (!dfs(i))
{
while (c > ) mark[s[--c]] = ;
if (!dfs(i+)) return false;
else
{
while (c > ) mark[s[--c]] = ;
ty[i/] = ;
}
}
else
{
while (c > ) mark[s[--c]] = ;
if (!dfs(i+))
{
ty[i/] = ;
while (c > ) mark[s[--c]] = ;
}
else
{
ty[i/] = ;
while (c > ) mark[s[--c]] = ;
}
}
}
else
{
if (mark[i]) ty[i/] = ;
else ty[i/] = ;
}
} return true;
} /*void judge()
{
for (int i = 0;i < n * 2;i += 2)
{
if (!mark[i] && !mark[i+1])
{
c = 0; bool tr = 0;
bool fa = 0; if (dfs(i))
{
fa = 1;
while (c > 0) mark[s[--c]] = 0;
} if (dfs(i+1))
{
tr = 1;
while (c > 0) mark[s[--c]] = 0;
} if (tr && fa) ty[i/2] = 3;
else if (tr) ty[i/2] = 2;
else ty[i/2] = 1;
}
else
{
//if (i == 0) printf("2333");
if (mark[i]) ty[i/2] = 1;
else ty[i/2] = 2;
}
}
}*/
}twosat; int main()
{
int n,m;
int kase = ; while (scanf("%d%d",&n,&m) != EOF)
{
if (n == && m == ) break; twosat.init(n); for (int i = ;i < m;i++)
{
int k;
scanf("%d",&k); int a[];
char ch[][]; for (int j = ;j < k;j++)
{
scanf("%d%s",&a[j],ch[j]);
a[j]--;
} //for (int j = 0;j < k;j++) vis[a[j]] = 1; if (k <= )
{
for (int j = ;j < k;j++)
{
if (ch[j][] == 'y') twosat.add_clause(a[j],,a[j],);
else twosat.add_clause(a[j],,a[j],);
}
}
else
{
bool b[]; for (int j = ;j < k;j++)
{
b[j] = ch[j][] == 'y' ? : ;
} for (int j = ;j < k;j++)
{
for (int l = ;l < k;l++)
{
if (j != l)
{
twosat.add_clause(a[j],b[j],a[l],b[l]);
}
}
}
}
} if (twosat.solve())
{
//twosat.judge(); printf("Case %d: ",++kase); for (int i = ;i < n;i++)
{
switch(twosat.ty[i])
{
case : printf("n");break;
case : printf("y");break;
case : printf("?");break;
}
}
printf("\n");
}
else printf("Case %d: impossible\n",++kase);
} return ;
}

uvalive 4452 The Ministers’ Major Mess的更多相关文章

  1. UVALive 4452 The Ministers' Major Mess(2-sat)

    2-sat.又学到了一种使用的方法:当确定选择某中状态A时,从它的对立状态A^1引一条边add(A^1,A),从而使凡是dfs经过对立状态,必然return false:即保证若存在一种可能性,必然是 ...

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

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

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

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

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

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

  5. uva1086 The Ministers' Major Mess

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

  6. 记一次jdk升级引起的 Unsupported major.minor version 51.0

    之前jdk 一直是1.6,tomcat 是6.x 版本,, 现在引入的新的jar, 出现 Caused by: java.lang.UnsupportedClassVersionError: org/ ...

  7. 解决Unsupported major.minor version 51.0错误

    解决Unsupported major.minor version 51.0错误使用jdk6运行项目时发生了Unsupported major.minor version 51.0错误.经过网上搜索发 ...

  8. Unsupported major.minor version 51.0

    org/jboss/as/domain/management/security/adduser/AddUser : Unsupported major.minor version 51. 0 已编译好 ...

  9. Unsupported major.minor version 52.0问题的解决

    下载Tomcat9.0,解压后安装运行,结果启动失败,进入logs文件夹看里面的日志文件,提示是Unsupported major.minor version 52.0错误,这是因为Tomcat版本过 ...

随机推荐

  1. DevOps理论与实践总结

    DevOps指导理论与实践 [第01篇]:郭宏泽:全开源架构下的DevOps实践(转) SonarQube应用指南 [第一篇]:SonarQube Scanner报svn: E170001错误 che ...

  2. linux 内核启动流程分析,移植

    分析 linux-2.6.22.6 内核启动流程 移植 linux-3.4.2 到 JZ2440 开发板 Linux内核源码百度云链接: https://pan.baidu.com/s/1m1ymGl ...

  3. 六、SpringBoot与数据访问

    六.SpringBoot与数据访问 1.JDBC spring: datasource: username: root password: 123456 url: jdbc:mysql://192.1 ...

  4. python练习题-day5

    1.有如下变量(tu是个元祖),请实现要求的功能 tu = ("alex", [11, 22, {"k1": 'v1', "k2": [&q ...

  5. 20170725 Python 必须使用的Url编码

    -- 1 原因:在进行API 调用传参时,如果出现了和区分参数标识一样的特殊字符,那么就需要编码来作用 或者,传递的参数有敏感数据. 我的目的: Python开发的接口,C#调用传递参数 先用C# 进 ...

  6. PowerTCP FTP for .NET 在线e文文档

    http://www.dart.com/help/ptftpnet/webframe.html

  7. mui项目中如何使用原生JavaScript代替jquery来操作dom

    最近在用mui写页面,当然了在移动App里引入jq或zepto这些框架,肯定是极不理性的.原生JS挺简单,为何需要jq?jq的成功当时是因为ie6.7.8.9.10.chrome.ff这些浏览器不兼容 ...

  8. Python处理Excel和PDF文档

    一.使用Python操作Excel Python来操作Excel文档以及如何利用Python语言的函数和表达式操纵Excel文档中的数据. 虽然微软公司本身提供了一些函数,我们可以使用这些函数操作Ex ...

  9. Case when then esle end

    Case具有两种格式.简单Case函数和Case搜索函数. --简单Case函数 CASE sex ' THEN '男' ' THEN '女' ELSE '其他' END --Case搜索函数 ' T ...

  10. [LeetCode] questions conlusion_InOrder, PreOrder, PostOrder traversal

    Pre: node 先,                      Inorder:   node in,           Postorder:   node 最后 PreOrder Inorde ...