「洛谷P1262」间谍网络 解题报告
P1262 间谍网络
题目描述
由于外国间谍的大量渗入,国家安全正处于高度的危机之中。如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B。有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报。所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子。因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报。
我们的反间谍机关提供了一份资料,包括所有已知的受贿的间谍,以及他们愿意收受的具体数额。同时我们还知道哪些间谍手中具体掌握了哪些间谍的资料。假设总共有n个间谍(n不超过3000),每个间谍分别用1到3000的整数来标识。
请根据这份资料,判断我们是否有可能控制全部的间谍,如果可以,求出我们所需要支付的最少资金。否则,输出不能被控制的一个间谍。
输入输出格式
输入格式:
第一行只有一个整数n。
第二行是整数p。表示愿意被收买的人数,1≤p≤n。
接下来的p行,每行有两个整数,第一个数是一个愿意被收买的间谍的编号,第二个数表示他将会被收买的数额。这个数额不超过20000。
紧跟着一行只有一个整数r,1≤r≤8000。然后r行,每行两个正整数,表示数对(A, B),A间谍掌握B间谍的证据。
输出格式:
如果可以控制所有间谍,第一行输出YES,并在第二行输出所需要支付的贿金最小值。否则输出NO,并在第二行输出不能控制的间谍中,编号最小的间谍编号。
输入输出样例
输入样例#1:
3
2
1 10
2 100
2
1 3
2 3
输出样例#1:
YES
110
输入样例#2:
4
2
1 100
4 200
2
1 2
3 4
输出样例#2:
NO
3
算法
缩点
思路
如果A掌握B的信息,那么我们就建有向边A->B,构成一个图。
每个点的权值就是收买该间谍需要花的钱,如果不能收买,那就赋为\(\infty\)。
我们的任务就是取Sum(点权)最少的若干个点,以这几个点为起点,能遍历整张图。
当然,Sum(点权)不能为\(\infty\)。(注意下 \(\infty + \infty = \infty \ \ ,\infty + x = \infty\))
因为在一个强连通分量中,任何一个点都能遍历到每个节点。所以,对于一个强连通分量,完全可以看成一个点,点权为该强连通分量包含的点的最小点权。
所以缩点即可。以下所说的点均为“缩”过的点。
入度为0的点绝对要取,而取来后绝对已经所有点都能访问到。
这个很好证明。入度为0的点绝对要取是不难理解的,因为它不可能被其他点访问。由于缩点后的图不可能构成环,所以入度不为0的点肯定可以被已经访问过的点访问到。
注意下不能被控制的(编号最小)点不一定入度为0。
如这组数据:
Input Data
4
1
4 100
4
2 4
2 1
4 3
1 3
Output Data
NO
1
代码
#include<bits/stdc++.h>
using namespace std;
#define MAXN 3005
#define MAXM 8005
int n, p, r;
int hd[MAXN], nxt[MAXM], to[MAXM], tot(1);
int dfn[MAXN], low[MAXN], num, stk[MAXN], tp, c[MAXN], cnt;
int pr[MAXN], f[MAXN];
int x, y;
bool vs[MAXN], v[MAXN];
void Add( int x, int y){ nxt[++tot] = hd[x]; hd[x] = tot; to[tot] = y; }
void Tarjan( int x ){
dfn[x] = low[x] = ++tot; stk[++tp] = x;
for ( int i = hd[x]; i; i = nxt[i] ){
if ( !dfn[to[i]] ) Tarjan( to[i] ), low[x] = min( low[x], low[to[i]] );
else if ( !c[to[i]] ) low[x] = min( low[x], dfn[to[i]] );
}
if ( low[x] == dfn[x] ){
c[x] = ++cnt; f[cnt] = pr[x];
while( stk[tp] != x ) f[cnt] = min( f[cnt], pr[stk[tp]] ), c[stk[tp--]] = cnt;
tp--;
}
}
//记忆化搜索
//Memory search
void DFS( int x ){
v[x] = 1;
for ( int i = hd[x]; i; i = nxt[i] )
if ( !v[to[i]] ) DFS( to[i] );
}
int main(){
scanf( "%d%d", &n, &p );
for ( int i = 1; i <= n; ++i ) pr[i] = INT_MAX;
for ( int i = 1; i <= p; ++i ) scanf( "%d%d", &x, &y ), pr[x] = y;
scanf( "%d", &r );
for ( int i = 1; i <= r; ++i ) scanf( "%d%d", &x, &y ), Add( x, y );
// 先判断是否能控制全部间谍,即把所有能收买的间谍都收买
// To see whether all spies can be under control.
for ( int i = 1; i <= n; ++i ) if ( pr[i] < INT_MAX && !v[i] ) DFS( i );
for ( int i = 1; i <= n; ++i ) if ( !v[i] ){ printf( "NO\n%d\n", i ); return 0; }
//------------------判断结束 Ended--------------------
//因为已经确定所有间谍都能被控制,那就大胆地取来所有入度为0的节点(当然,是缩点后的图)
// Because all spies can be controled, get all ponits which has no indegree(After Tarjan, certainly).
for ( int i = 1; i <= n; ++i ) if ( !c[i] ) Tarjan( i );
//当然, 并不需要建边,可以直接判断入度是否为0
//Certainly, it is unnecessary to connect edges.You can DIRECTLY know whether a point has no indegree.
for ( int i = 1; i <= n; ++i )
for ( int j = hd[i]; j; j = nxt[j] )
if ( c[i] != c[to[j]] ) vs[c[to[j]]] = 1;
int ans(0);
for ( int i = 1; i <= cnt; ++i ) if ( !vs[i] ) ans += f[i];
printf( "YES\n%d\n", ans );
return 0;
}
注:为了防止中文乱码情况,代码注释给出英文版。
「洛谷P1262」间谍网络 解题报告的更多相关文章
- 「洛谷P1402」酒店之王 解题报告
P1402 酒店之王 题目描述 XX酒店的老板想成为酒店之王,本着这种希望,第一步要将酒店变得人性化.由于很多来住店的旅客有自己喜好的房间色调.阳光等,也有自己所爱的菜,但是该酒店只有p间房间,一天只 ...
- 「洛谷P1343」地震逃生 解题报告
P1343 地震逃生 题目描述 汶川地震发生时,四川XX中学正在上课,一看地震发生,老师们立刻带领x名学生逃跑,整个学校可以抽象地看成一个有向图,图中有n个点,m条边.1号点为教室,n号点为安全地带, ...
- 「洛谷P1233」木棍加工 解题报告
P1233 木棍加工 题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的.棍子可以被一台机器一个接一个地加工.机器处理一根棍子之前需要准备时间.准备时间是这样定义的: 第一根棍子的准备时间 ...
- 「洛谷P1198」 [JSOI2008]最大数 解题报告
P1198 [JSOI2008]最大数 题目描述 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作. 语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值. 限制: ...
- 「洛谷P3469」[POI2008]BLO-Blockade 解题报告
P3469[POI2008]LO-Blockade 题意翻译 在Byteotia有n个城镇. 一些城镇之间由无向边连接. 在城镇外没有十字路口,尽管可能有桥,隧道或者高架公路(反正不考虑这些).每两个 ...
- 缩点【洛谷P1262】 间谍网络
[洛谷P1262] 间谍网络 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他 ...
- 洛谷 P1262 【间谍网络】
题库 : 洛谷 题号 : 1262 题目 : 间谍网络 link : https://www.luogu.org/problemnew/show/P1262 思路 : 这题可以用缩点的思想来做.先用T ...
- 「区间DP」「洛谷P1043」数字游戏
「洛谷P1043」数字游戏 日后再写 代码 /*#!/bin/sh dir=$GEDIT_CURRENT_DOCUMENT_DIR name=$GEDIT_CURRENT_DOCUMENT_NAME ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
随机推荐
- 【Android内存机制分析】了解Android堆和栈
昨天用Gallery做了一个图片浏览选择开机画面的功能,当我加载的图片多了就出现OOM问题.以前也出现过这个问题,那时候并没有深究.这次打算好好分析一下Android的内存机制. 因为我以前是做VC+ ...
- 解决TortoiseSVN中out of date问题的一个方法
http://blog.csdn.net/freefalcon/article/details/645058 从去年开始,公司的代码管理从CVS转向了subvsersion,后者确实是前者的一个飞跃, ...
- PHP 试题(1)
1.__FILE__表示什么意思?(5分)文件的完整路径和文件名.如果用在包含文件中,则返回包含文件名.自 PHP 4.0.2 起,__FILE__ 总是包含一个绝对路径,而在此之前的版本有时会包含一 ...
- hdu 1595 find the longest of the shortest(迪杰斯特拉,减去一条边,求最大最短路)
find the longest of the shortest Time Limit: 1000/5000 MS (Java/Others) Memory Limit: 32768/32768 ...
- 版本号/缓存刷新 laravel mix函数
很多开发者会给编译的前端资源添加时间戳或者唯一令牌后缀以强制浏览器加载最新版本而不是代码的缓存副本.Mix 可以使用 version 方法为你处理这种场景. version 方法会自动附加唯一哈希到已 ...
- 如何查看linux中的ssh端口开启状态
netstat -anp |grep 22 netstat -anp |grep sshlsof -i :22
- 移动端遇到的bug (长期更新)
移动端遇到的bug border-radius和transform在一起的bug 当父级设置了border-radius+overflow:hidden的时候,圆角是可以包住子级的,这是个很常见的场景 ...
- linux Tasklet 实现
记住 tasklet 是一个特殊的函数, 可能被调度来运行, 在软中断上下文, 在一个系统决 定的安全时间中. 它们可能被调度运行多次, 但是 tasklet 调度不累积; ; tasklet 只 运 ...
- 微信里首次跳转会到首页问题(window.location失效)
将window.location.href 换为location.href
- vue-learning:26 - component - 组件三大API之一:prop
组件三大API之一: prop prop的大小写 prop接收类型 字符串数组形式 对象形式: type / required / default / validator prop传递类型: 静态传递 ...