题意:

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

一个部长最多对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. elasticsearch最大的条件数设置

    elasticsearch  bool条件查询里面条件的数量是有限制的,比如terms里面相等的值的数量个数 添加: indices.query.bool.max_clause_count: 1000 ...

  2. codechef Sum of Cubes 图论

    正解:图论+数学 解题报告: 先放个传送门QwQ 然后放下题目大意?就说给定简单图,无自环或重边,然后求(∑e[i][j])k,i,j∈S,S为点集的子集 然后因为k的取值只有[1,3],所以这里分类 ...

  3. redis缓存和mysql数据库同步

    附redis关于缓存雪崩和缓存穿透,热点key 穿透 穿透:频繁查询一个不存在的数据,由于缓存不命中,每次都要查询持久层.从而失去缓存的意义. 解决办法: 持久层查询不到就缓存空结果,查询时先判断缓存 ...

  4. 初学git

    初学git,总结了一点东西,可能有理解和操作的不到位的地方,还有就是这个是我之前写在word上的,因为CSDN上不能直接上传,所以拷贝的过程中也可能有其他问题.发的的朋友还望指正... 1.找到“参与 ...

  5. IE8“开发人员工具”(下)

    浏览器模式 说白了,就是让用户选择当前页面用何种IE版本去渲染. 文本模式 说起“文本模式”这个名词,这又要回到渲染页面的3种模式了:诡异模式(Quirks mode,也有翻译为兼容模式.怪异模式的) ...

  6. 定义结构体和table type

    1: 在se11 中创建结构体 2: 定义一个内表, row type 使用structure类型,将会具有structure的字段. 3:在代码中 使用 结构体和table  type *& ...

  7. Marathon自动扩缩容(marathon-lb-autoscale)

    我们在服务里面创建如下的应用(以下是创建完复制过来的json): { "id": "/nginxtest", "cmd": null, &q ...

  8. Python 数据结构 树

    什么是树 数是一种抽象的数据类型(ADT)或是作这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合,它是由n(n>1)的有限个节点和节点之间的边组成的一个有层次关系的集合. 树的组成 ...

  9. shell的函数返回值

    1.默认function的返回值包含0 和1,执行成功,返回0,执行失败,返回1,可以采用$?来获取执行结果 2.函数如何返回字符串呢,可以采用echo函数 #!/bin/bashfunction t ...

  10. WINDOWS SERVER 2008远程桌面端口修改方法

    微软默认的服务器远程端口是3389,这是被很多黑客利用的端口,如何修改掉了,下面我们来说方法很多朋友在使用WINDOWS操作系统的时候,都喜欢修改远程连接的默认端口.但是很多朋友由于修改端口的方法错误 ...