[OpenJudge 3063]罪犯问题
[OpenJudge 3063]罪犯问题
试题描述
一天,警官抓获了N个嫌犯,审问N个罪犯的途中,作为警长助手的你突然发现其中被确定为罪犯的K号人是你曾经出生入死的兄弟,你不能眼睁睁看着他被抓进牢里。
审问完了嫌犯之后,发现每个人都说话了,并且每个人只说了一句话,说的话形式有两种,“XXX是罪犯”以及“XXX不是罪犯”,并且罪犯说的都是假话,不是罪犯的说的都是真话(每人说的话均不是说自己)。
因为见过其中M个人的通缉令(不包括你的兄弟),镇长可以确定这M个人是罪犯。
通过这些情况可推断出大部分人是不是罪犯。每个人说话的内容都已经存入了资料库之中,现在你需要冒险修改资料库中某些人说话的内容使得你兄弟摆脱的罪犯嫌疑(必须修改后确定他不是罪犯)。
当然修改后的资料库数据不能存在矛盾,修改的条数越多,风险也就越大,现在希望你能求出最少要修改资料库中几个人说的话。
输入
第一行,三个整数N,M,K,分别表示嫌犯个数,被确定的罪犯个数以及你兄弟的编号。
第二行,M个整数,第i个整数Ti表示编号Ti的嫌犯确定是罪犯。
第3-N+2行,第i+2行有一个整数X,若X大于零,表示编号为i嫌犯的人说“X号是罪犯”;若X小于零,表示编号i为嫌犯的居民说“-X号不是罪犯”。
对于100%的数据,N<=200000,1<=M<=N;
数据保证嫌犯说的话不存在矛盾,且K号本为罪犯且未在通缉令上。
输出
仅一个整数,表示最少需修改资料库中几人说的话,使得你兄弟摆脱罪犯的嫌疑。
输入示例
-
-
-
输出示例
数据规模及约定
见“输入”
题解
这题挺绕的,我题意理解了半天。稍加分析发现给出的信息是正的还是负的并不影响最终答案,因为题目中保证了输入合法。
那么对于一条给出的信息“x 说 y (不)是罪犯”,其实是告诉我们,如果确定了 x 的身份,则能够确定 y 的身份;反之,如果知道了 y 的身份,就进一步能确定 x 的身份。那么现在有 m 个人的身份已知,目的是不能通过这 m 个已知的人的身份确定 k 的身份。再进一步解释就是:对于每一条信息建双向边,割断最少数量的边,使得从给定的 m 个人出发,没有一条路径能够到达 k;这显然就是一个最小割了,建一个超级源点向给定的 m 人连容量无穷的边,再把 k 看成汇点,跑一边最小割就行了。
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
#include <cstdlib>
using namespace std; int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 200010
#define maxm 801010
#define oo 2147483647 struct Edge { int from, to, flow; } ;
struct Dinic {
int n, m, s, t, head[maxn], next[maxm];
Edge es[maxm];
int vis[maxn], Q[maxn], hd, tl;
int cur[maxn];
void init(int _) {
n = _;
m = 0; memset(head, -1, sizeof(head));
return ;
}
void AddEdge(int a, int b, int c) {
es[m] = (Edge){ a, b, c }; next[m] = head[a]; head[a] = m++;
return ;
}
bool BFS() {
memset(vis, 0, sizeof(vis));
hd = tl = 0; Q[++tl] = s;
vis[s] = 1;
while(hd < tl) {
int u = Q[++hd];
for(int i = head[u]; i != -1; i = next[i]) {
Edge& e = es[i];
if(!vis[e.to] && e.flow) {
vis[e.to] = vis[u] + 1;
Q[++tl] = e.to;
}
}
}
return vis[t] > 0;
}
int DFS(int u, int a) {
if(u == t || !a) return a;
int flow = 0, f;
for(int& i = cur[u]; i != -1; i = next[i]) {
Edge& e = es[i];
if(vis[e.to] == vis[u] + 1 && (f = DFS(e.to, min(a, e.flow)))) {
flow += f; a -= f;
e.flow -= f; es[i^1].flow += f;
if(!a) return flow;
}
}
return flow;
}
int MinCut(int _, int __) {
s = _; t = __;
int flow = 0;
while(BFS()) {
for(int i = 1; i <= n; i++) cur[i] = head[i];
flow += DFS(s, oo);
}
return flow;
}
} sol; int main() {
int n = read(), m = read(), k = read(); sol.init(n + 2); int s = n + 1, t = n + 2;
for(int i = 1; i <= m; i++) {
int x = read();
sol.AddEdge(s, x, oo), sol.AddEdge(x, s, 0);
}
for(int i = 1; i <= n; i++) {
int x = abs(read());
sol.AddEdge(i, x, 1); sol.AddEdge(x, i, 1);
}
sol.AddEdge(k, t, oo); sol.AddEdge(t, k, 0); printf("%d\n", sol.MinCut(s, t)); return 0;
}
[OpenJudge 3063]罪犯问题的更多相关文章
- 关押罪犯 and 食物链(并查集)
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用"怨气值"( ...
- 并查集补集作法 codevs 1069 关押罪犯
1069 关押罪犯 2010年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description ...
- NOIP2010关押罪犯[并查集|二分答案+二分图染色 | 种类并查集]
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
- 【OpenJudge 8463】Stupid cat & Doge
http://noi.openjudge.cn/ch0204/8463/ 挺恶心的一道简单分治. 一开始准备非递归. 大if判断,后来发现代码量过长,决定大打表判断后继情况,后来发现序号不对称. 最后 ...
- 【OpenJudge 191】【POJ 1189】钉子和小球
http://noi.openjudge.cn/ch0405/191/ http://poj.org/problem?id=1189 一开始忘了\(2^{50}\)没超long long差点写高精度Q ...
- 【OpenJudge 1665】完美覆盖
http://noi.openjudge.cn/ch0405/1665/?lang=zh_CN 状压水题,手动转移 #include<cstdio> #include<cstring ...
- 【OpenJudge 1793】矩形覆盖
http://noi.openjudge.cn/ch0405/1793/ 好虐的一道题啊. 看数据范围,一眼状压,然后调了好长时间QwQ 很容易想到覆盖的点数作为状态,我用状态i表示至少覆盖状态i表示 ...
- OpenJudge 2990:符号三角形 解析报告
2990:符号三角形 总时间限制: 1000ms 内存限制: 65536kB 描述 符号三角形的第1行有n个由“+”和”-“组成的符号 ,以后每行符号比上行少1个,2个同号下面是”+“ ...
- NOIP提高组2010 关押罪犯
题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示 ...
随机推荐
- jQuery Easy UI 开发笔记
1.jQuery Easy UI主要的运行原理是通过核心的代码调用插件来实现UI效果的 2.jQuery Easy UI插件与插件之间的关系是: 一.独立式插件: 独立式插件是指:不与其他的插件具有相 ...
- ubuntu安装 laravel 过程中出现: mcrypt php extension required 的问题 | 以及composer相关问题 | Nginx安装
这篇文章对于Nginx的配置至关重要 如果碰到访问index.php不返回html而出现下载文件的问题,加上那段default就可以修正: https://www.digitalocean.com/c ...
- express 笔记 app.helpers 和 app.locals
app.helpers 和app.dynamicHelpers 是express2.X使用的 分别为静态/动态 视图助手通过其注册函数, 例如 app.helpers({ <span style ...
- 编写高质量代码改善C#程序的157个建议[勿选List<T>做基类、迭代器是只读的、慎用集合可写属性]
前言 本文已更新至http://www.cnblogs.com/aehyok/p/3624579.html .本文主要学习记录以下内容: 建议23.避免将List<T>作为自定义集合类的基 ...
- 第二章:Javascript词法结构
编程语言的词法结构是一套基础性的规则,用来描述你如何编写这门语言.作为语法的基础,它规定了变量名是怎么样的,如何写注释,以及语句之间是如何区分的.本节用很短的篇幅来介绍javascript的词法结构. ...
- HTML5——单次定位请求
单次定位请求及点击一次只发出一次请求 下面是个获取经纬度的简单Demo 简要截图如下: 简要代码如下: <!DOCTYPE html> <html> <head> ...
- 第五次课堂总结x
一.知识点: 1.while语句 循环体语句: while语句里的表达式可以是任何合法的表达式,循环体则只可以表达一条语句. while的循环体语句需要能改变循环条件的真假条件. ...
- sql- 别名alias(as)
alias (别名) 在 SQL 上的用处.最常用到的别名有两种: 栏位别名及表格别名. 简单地来说,栏位别名的目的是为了让 SQL 产生的结果易读.在之前的例子中,每当我们有营业额总合时,栏位名都是 ...
- 【BZOJ-1030】文本生成器 AC自动机 + DP
1030: [JSOI2007]文本生成器 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3253 Solved: 1330[Submit][Stat ...
- 【SDOI2008】解题汇总
好叭我真的是闲的了... /---------------------------------------------/ BZOJ-2037 [SDOI2008]Sue的小球 DP+相关费用提前计算 ...