bzoj 2199: [Usaco2011 Jan]奶牛议会
来源:互联网 发布:msp430用什么软件 编辑:程序博客网 时间:2024/05/16 14:13
Description
由于对Farmer John的领导感到极其不悦,奶牛们退出了农场,组建了奶牛议会。议会以“每头牛 都可以获得自己想要的”为原则,建立了下面的投票系统: M只到场的奶牛 (1 <= M <= 4000) 会给N个议案投票(1 <= N <= 1,000) 。每只 奶牛会对恰好两个议案 B_i and C_i (1 <= B_i <= N; 1 <= C_i <= N)投 出“是”或“否”(输入文件中的'Y'和'N')。他们的投票结果分别为VB_i (VB_i in {'Y', 'N'}) and VC_i (VC_i in {'Y', 'N'})。 最后,议案会以如下的方式决定:每只奶牛投出的两票中至少有一票和最终结果相符合。 例如Bessie给议案1投了赞成'Y',给议案2投了反对'N',那么在任何合法的议案通过 方案中,必须满足议案1必须是'Y'或者议案2必须是'N'(或者同时满足)。 给出每只奶牛的投票,你的工作是确定哪些议案可以通过,哪些不能。如果不存在这样一个方案, 输出"IMPOSSIBLE"。如果至少有一个解,输出: Y 如果在每个解中,这个议案都必须通过 N 如果在每个解中,这个议案都必须驳回 ? 如果有的解这个议案可以通过,有的解中这个议案会被驳回 考虑如下的投票集合: - - - - - 议案 - - - - - 1 2 3 奶牛 1 YES NO 奶牛 2 NO NO 奶牛 3 YES YES 奶牛 4 YES YES 下面是两个可能的解: * 议案 1 通过(满足奶牛1,3,4) * 议案 2 驳回(满足奶牛2) * 议案 3 可以通过也可以驳回(这就是有两个解的原因) 事实上,上面的问题也只有两个解。所以,输出的答案如下: YN?
Input
* 第1行:两个空格隔开的整数:N和M * 第2到M+1行:第i+1行描述第i只奶牛的投票方案:B_i, VB_i, C_i, VC_i
Output
* 第1行:一个含有N个字符的串,第i个字符要么是'Y'(第i个议案必须通过),或者是'N' (第i个议案必须驳回),或者是'?'。 如果无解,输出"IMPOSSIBLE"。
上了黑板手推就是思路比较清晰呀。关系很一样,也就是“或”的关系,不过问法比较有意思,问的是第i个议案是必须被通过,必须不被通过,可被也可不被,还是不属于任何方案。
翻译一下题意就是,如果某个可行解包含Y,却没有可行解包含N,就输出Y,以此类推。
不知道有没有可行解能包含它,我们就拿它构造可行解啊,如果能构造出来可行解就可行,构造不出来就不行,由于连的边是依赖关系,所以我们可以一直走,走到没有依赖关系为止,看有没有一个点的正反被这个可行解同时包含即可。
下附AC代码。
#include<iostream>#include<stdio.h>#include<string.h>#include<algorithm>#include<stack>#define maxn 3000005using namespace std;//0:选,1:不选,2:存在,3:不存在 int n,m,k,tot,num,cnt;int head[maxn<<2],to[6*maxn],nex[6*maxn],pre[6*maxn];void add(int x,int y){to[++tot]=y;nex[tot]=head[x];head[x]=tot;}int low[maxn<<2],dfn[maxn<<2],bel[maxn<<2];bool vis[maxn<<2];stack<int>s;void tarjan(int now){low[now]=dfn[now]=++cnt;vis[now]=1;s.push(now);for(int i=head[now];i;i=nex[i]){if(!dfn[to[i]]){tarjan(to[i]);low[now]=min(low[now],low[to[i]]);}else if(vis[to[i]]){low[now]=min(low[now],dfn[to[i]]);}}if(low[now]==dfn[now]){num++;int temp;do{temp=s.top();s.pop();bel[temp]=num;vis[temp]=0;}while(temp!=now);}return;}int main(){memset(pre,-1,sizeof(pre));scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=m;i++){int x,y;scanf("%d%d",&x,&y);x--;y--;int x1=((x<<2)|1),y1=((y<<2)|1);x<<=2;y<<=2;add(x1,y);add(y1,x);}for(int i=1;i<=k;i++){int x,last;scanf("%d%d",&x,&last);last--;for(int j=1;j<x;j++){int y;scanf("%d",&y);y--;pre[y]=last;last=y;}}for(int i=0;i<n;i++){int x1=(i<<2),x2=(x1|1),x3=(x2+1),x4=(x3+1);add(x1,x3);add(x4,x2);if(pre[i]!=-1){int j=pre[i];int y1=(j<<2),y2=(y1|1),y3=(y2+1),y4=(y3+1);add(y3,x3);add(x4,y4);add(y3,x2);add(x1,y4);}} for (int i=0;i<(n<<2);i++) if (!dfn[i]) tarjan(i); for (int i=0;i<(n<<2);i++) if (bel[i]==bel[i^1]) {printf("NIE");return 0;}printf("TAK\n");return 0;}
阅读全文
0 0
- bzoj 2199: [Usaco2011 Jan]奶牛议会
- 2199: [Usaco2011 Jan]奶牛议会
- |BZOJ 2199|2-SAT|[Usaco2011 Jan]奶牛议会
- BZOJ 2199: [Usaco2011 Jan]奶牛议会 2-sat
- 2199: [Usaco2011 Jan]奶牛议会 2-SAT
- bzoj2199 [Usaco2011 Jan]奶牛议会
- bzoj 2199: [Usaco2011 Jan]奶牛议会 (2-SAT+拓扑序+bitset)
- [BZOJ2199][Usaco2011 Jan][2-SAT]奶牛议会
- bzoj2199 [Usaco2011 Jan]奶牛议会 2-SAT
- [bzoj2199][Usaco2011 Jan]奶牛议会 2-sat
- 【2-SAT】BZOJ2199 [Usaco2011 Jan]奶牛议会
- [BZOJ2199][Usaco2011 Jan]奶牛议会(2-SAT)
- BZOJ2199: [Usaco2011 Jan]奶牛议会(2-SAT+DP)
- BZOJ 2200: [Usaco2011 Jan]道路和航线
- bzoj2199 奶牛议会
- BZOJ 1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会
- BZOJ 1612: [Usaco2008 Jan]Cow Contest奶牛的比赛
- 【BZOJ】1654: [Usaco2006 Jan]The Cow Prom 奶牛舞会
- android 透明布局点击不穿透的处理
- 叉乘与反对称矩阵
- java调用摄像头推流demo(针对不同处理器和操作系统)
- Length of Last Word
- 《Java 编程技巧1001条》 第404条 了解实用方法
- bzoj 2199: [Usaco2011 Jan]奶牛议会
- C#基础知识简单梳理
- Cloudera Manager和CDH5.11.0升级流程
- bzoj4213 贪吃蛇
- 重构客户注册-基于ActiveMQ实现短信验证码生产者
- MongoDB的安装与配置
- binder原理
- 应用部署的六种策略
- JAVA实现约瑟夫环