题意:

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

一个部长最多对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. 使用Jersey上传文件

    采用jquery.form.js异步上传图片,并结合<form>表单 <script type="text/javascript"> //采用jquery. ...

  2. magento 2.3安装测试数据

    前面我们一步步composer安装Magento2.3,但是没有数据的话各项设置不是很熟悉,所以最好还是安装一下测试数据.下面我们就跟ytkah一起填充数据.假设magento 2.3安装目录是/ww ...

  3. cxGrid常用属性设置

    OptionsView部分 是否使用表头分组:cxGrid1DBTableView1.OptionsView.GroupByBox 单元格高度自适应:cxGrid1DBTableView1.Optio ...

  4. C++的函数功能总结

    1. string中find()返回值是字母在母串中的位置(下标记录),如果没有找到,返回npos. 2.string的substr(pos=0, count=npos)返回字符串[pos, pos+ ...

  5. python按修改时间顺序排列文件

    import os def sort_file_by_time(file_path): files = os.listdir(file_path) if not files: return else: ...

  6. 282A

    #include <iostream> #include <string> using namespace std; int main() { int n, plus, sub ...

  7. MySQL 基础 事务

    什么是mysql的事务 MySQL 事务主要用于处理操作量大,复杂度高的数据.简单的说,事务就是一连串的DML的sql语句组合在一起,所以语句执行成功才算成功,如果有语句执行失败,执行就不成功 .比如 ...

  8. yum 安装报错 File "/usr/bin/yum", line 30 except KeyboardInterrupt, e:

    原因: 这是因为yum采用python作为命令解释器,这可以从/usr/bin/yum文件中第一行#!/usr/bin/python发现.而python版本之间兼容性不太好,使得2.X版本与3.0版本 ...

  9. react全局的公共组件-------弹框 (Alert)

    最近研究react,发现写一个组件很容易,但是要写一个全局的好像有点麻烦.不能像VUE一样,直接在原型上面扩展,注册全局组件 下面实现一个弹框,只需要引入之后,直接调用方法即可,不需要写入组件 给出我 ...

  10. Java Selenium - 元素定位(一)

    一,单个元素对象定位 Webdriver通过findElement() , findElements()等方法调用By对象来定位和查询元素 , findElement()返回一个元素对象,否则抛出异常 ...