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

数据范围:n≤1000,m≤5000,1≤ki≤4

首先这是一些布尔变量的真假的问题,这让我们联想到2-SAT

仔细观察题意发现,k=1,2的时候所投的1个/2个提议的结果必须和投的票相同,k=3和4的时候最多允许有一个提议的结果和投的票不同.

因为2-SAT问题是对两个变量的约束,我们发现,如果k=3,某个人要求A,B,C三个变量至少两个为真,那么这三个变量中任意两个至少一个为真,也就是”A或B”,”B或C”,”A或C”

K=4的时候,添加6条限制即可.

接下来枚举每个变量的取值,分别添加某个变量必须为真/假的条件,用线性做法做2n次2-SAT,然后这样是卡在1s左右.我们发现,只要找出一个可行方案,就能对n个变量都给出一个可行的取值,然后就把2-SAT次数减少到了n次,就可以过了

吐槽:考试的题是单组数据,UVA上多组数据,输出格式还不一样…加初始化,改输出格式的时候挂了5次(最有趣的一次是考试的时候没有输出文末回车因为是单组数据没出事,多组数据的时候就成了每组数据的输出之间没有回车…)

#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
const int maxn=,maxm=;
struct edge{
int to,next;
}lst[maxm],lst2[maxm];int len=,first[maxn],len2=,first2[maxn];
void addedge(int a,int b){//printf("%d %d\n",a,b);
lst[len].to=b;lst[len].next=first[a];first[a]=len++;
}
void addedge2(int a,int b){//printf("%d->%d\n",a,b);
lst2[len2].to=b;lst2[len2].next=first2[a];first2[a]=len2++;
}
int conv[maxn][];int ok[maxn][];
void AddTrue(int x){
addedge(conv[x][],conv[x][]);
}
void AddFalse(int x){
addedge(conv[x][],conv[x][]);
}
void AddOr(int x1,int t1,int x2,int t2){
addedge(conv[x1][t1^],conv[x2][t2]);addedge(conv[x2][t2^],conv[x1][t1]);
}
int n,m,k;
int a[],b[];char buf[];
int s[maxn],top,dfn[maxn],low[maxn],belong[maxn],tot,T;
bool ins[maxn];
void dfs(int x){
s[top++]=x;ins[x]=true;
dfn[x]=low[x]=++T;
for(int pt=first[x];pt;pt=lst[pt].next){
if(!dfn[lst[pt].to]){
dfs(lst[pt].to);
if(low[lst[pt].to]<low[x])low[x]=low[lst[pt].to];
}else if(ins[lst[pt].to]&&dfn[lst[pt].to]<low[x])low[x]=dfn[lst[pt].to];
}
if(low[x]==dfn[x]){
++tot;
do{
ins[s[--top]]=false;belong[s[top]]=tot;
}while(s[top]!=x);
}
}
bool Tarjan(){
memset(dfn,,sizeof(dfn));T=;tot=;
for(int i=;i<=n;++i){
if(!dfn[conv[i][]])dfs(conv[i][]);
if(!dfn[conv[i][]])dfs(conv[i][]);
if(belong[conv[i][]]==belong[conv[i][]])return false;
}
return true;
} int sz[maxn];int choose[maxn];bool vis[maxn];
int toposeq[maxn];int cnt=;
void toposort(int x){
if(vis[x])return;
vis[x]=true;
for(int pt=first2[x];pt;pt=lst2[pt].next){
toposort(lst2[pt].to);
}
toposeq[++cnt]=x;
}
int neg(int x){
return (x&)?(x+):(x-);
}
void get_solution(){
vector<int> scc[maxn];
int lim=*n;cnt=;
for(int i=;i<=lim;++i)sz[belong[i]]++,scc[belong[i]].push_back(i);
for(int i=;i<=lim;++i){
for(int pt=first[i];pt;pt=lst[pt].next){
if(belong[i]!=belong[lst[pt].to]){
addedge2(belong[i],belong[lst[pt].to]);
}
}
}
for(int i=;i<=tot;++i){
if(!vis[i])toposort(i);
}
for(int i=;i<=cnt;++i){
int x=toposeq[i];int flag=;//printf("%d\n",x);
if(choose[x]!=)continue;
for(int pt=first2[x];pt;pt=lst2[pt].next){
if(choose[lst2[pt].to]==-){
flag=-;break;
}
}
choose[x]=flag;
for(int j=;j<sz[x];++j){
choose[belong[neg(scc[x][j])]]=-flag;
}
}//printf("%d %d\n",choose[belong[conv[2][0]]],choose[belong[conv[2][1]]]);
for(int i=;i<=n;++i){
if(choose[belong[conv[i][]]]==){
ok[i][]=;
}else{
ok[i][]=;
}
}
}
void work(){
for(int i=n;i>=;--i){
for(int k=;k<;++k){
if(ok[i][k]==)continue;
int tmp=first[conv[i][k^]];
if(k==)AddTrue(i);
else AddFalse(i);
if(Tarjan()){
ok[i][k]=;
}
len--;
first[conv[i][k^]]=tmp;
}
}
}
int main(){
int t=;
while(scanf("%d%d",&n,&m),n!=){ memset(first,,sizeof(first));len=;memset(first2,,sizeof(first2));len2=;
memset(conv,,sizeof(conv));memset(ok,,sizeof(ok));
memset(choose,,sizeof(choose));memset(vis,,sizeof(vis));
memset(sz,,sizeof(sz));
for(int i=;i<=n;++i){
conv[i][]=*i-;conv[i][]=*i-;
}
for(int i=;i<=m;++i){
scanf("%d",&k);
for(int j=;j<=k;++j){
scanf("%d",&a[j]);
scanf("%s",buf);
if(buf[]=='y')b[j]=;
else b[j]=;
}
if(k==){
if(b[]==)AddTrue(a[]);
else AddFalse(a[]);
}else if(k==){
for(int j=;j<=;++j){
if(b[j]==)AddTrue(a[j]);
else AddFalse(a[j]);
}
}else{
for(int j=;j<=k;++j){
for(int l=j+;l<=k;++l){
AddOr(a[j],b[j],a[l],b[l]);
}
}
}
}
printf("Case %d: ",++t);
if(Tarjan()){
get_solution();
work();
for(int i=;i<=n;++i){
if(ok[i][]==&&ok[i][]==)printf("?");
else printf("%c",(ok[i][]==)?'n':'y');
}printf("\n");
}else{
puts("impossible");
}
}
return ;
}

uva1086 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

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

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

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

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

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

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

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

  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. MySQL高级第二章——索引优化分析

    一.SQL性能下降原因 1.等待时间长?执行时间长? 可能原因: 查询语句写的不行 索引失效(单值索引.复合索引) CREATE INDEX index_user_name ON user(name) ...

  2. 《图说VR入门》——googleVR入门

    本文章由cartzhang编写,转载请注明出处. 所有权利保留. 文章链接:http://blog.csdn.net/cartzhang/article/details/52959035 作者:car ...

  3. 北京Uber优步司机奖励政策(1月19日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. 南京Uber优步司机奖励政策(7.20~7.26)

    人民优步奖励前提   *必须满足当周平均评分4.5星及以上,且当周接单率70%及以上,满足以上所有前提即可获得当周奖励 *刷单和红线行为立即封号并取消当周全部奖励及车费! 滴滴快车单单2.5倍,注册地 ...

  5. 「日常训练」Card Game Cheater(HDU-1528)

    题意与分析 题意是这样的:有\(n\)张牌,然后第一行是Adam的牌,第二行是Eve的牌:每两个字符代表一张牌,第一个字符表示牌的点数,第二个表示牌的花色.Adam和Eve每次从自己的牌中选出一张牌进 ...

  6. 「Python」Numpy equivalent of MATLAB's cell array

    转自Stackoverflow.备忘用. Question I want to create a MATLAB-like cell array in Numpy. How can I accompli ...

  7. Qt-QML-Connections,接受组件信号

    这里还没有什么新的体会.就直接上代码,在上篇一处上改出来的 import QtQuick 2.5 import QtQuick.Controls 1.4 ApplicationWindow { vis ...

  8. 垃圾收集器与内存分配策略(深入理解Java虚拟机)

    3.1 概述 垃圾收集器要解决哪些问题? 哪些内存需要回收 什么时候回收 如何回收 引用计数算法:当有一个地方引用,+1,引用失效,-1.     缺点:对象之间相互循环引用的问题. 可达性分析算法: ...

  9. Python3 Tkinter-Frame

    1.创建 from tkinter import * root=Tk() for fm in ['red','blue','yellow','green','white','black']: Fram ...

  10. [leetcode-662-Maximum Width of Binary Tree]

    Given a binary tree, write a function to get the maximum width of the given tree. The width of a tre ...