[Luogu 1262] 间谍网络
题目描述
由于外国间谍的大量渗入,国家安全正处于高度的危机之中。如果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:
YES
输出样例#2:
NO
My Solution :
还不是很懂 Tarjan 缩点的戳这里w -> 简要了解 Tarjan 缩点!
感觉很神奇的一道题,让我仅仅是按照思路实现一遍代码就用了一个小时,结果没过样例;又调试了半个小时才过。
涉及到以下步骤:
1、染色缩点:Tarjan 染色缩点同时处理连通块个数(很简单而且个数这个好像没卵用);
2、重新建图:按照缩点后的图重新建图,并统计新图的入度,以便于之后的搜索(之前做过的题都没必要有这个步骤……可能那就是裸题吧);
3、初始化花费:若一个点(以下提到的均为缩点后的点,即连通块)中有可收买的间谍,则这个点可控制,将其收买的价值 cost[](初值为 0x3f3f3f3f)取 min 更新,为收买它要用的最少金额;
4、深搜更新:更新从一个点 u 能到达的点 v 即 v 能被 u 所控制,故从入度为零的点开始 Dfs,更新每个点被控制所需的最小价格(记得过程中也要取 min,因为也许始点不能被控制而路径上出现了能被收买的点,不取 min 会影响第 5 步中的判断,详见代码,这里让我WA了一个点);
5、枚举判断:最后枚举所有间谍,查询 cost[ col[i] ](即控制其所在连通块的最小价值)是否仍为 0x3f3f3f3f,如果是,则此间谍无法被控制,GG;否则输出 ans;
6、输出答案:关于 ans,即收买最小金额的统计,因为入度为 0 的点只能进行收买而无法被控制,所以 ans 即为第 3 步之后,所有入度为零的点的 cost[] 之和,在第 4 步中一起统计好即可。
放个杂乱的代码,Tarjan 真是太有用了:
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int maxn = + ;
const int maxm = + ;
int n, m, p, head[maxn], dfn_num, col_num, edge_num;
int buy[maxn], val[maxn], deg[maxn], cost[maxn], con[maxn];
int dfn[maxn], low[maxn], vis[maxn], col[maxn], cnt[maxn], stack[maxn], top; struct Edge{ int u, v, nxt; }edge[maxm]; inline int read() {
register char ch = ; register int w = , x = ;
while( !isdigit(ch) ) w |= (ch == '-'), ch = getchar();
while( isdigit(ch) ) x = (x * ) + (ch ^ ), ch = getchar();
return w ? -x : x;
} inline void Add_edge(int u, int v) {
edge[++edge_num].u = u, edge[edge_num].v = v;
edge[edge_num].nxt = head[u], head[u] = edge_num;
} void Tarjan(int s) {
dfn[s] = low[s] = ++dfn_num;
vis[s] = , stack[++top] = s;
for(int i = head[s]; i; i = edge[i].nxt) {
if( !dfn[edge[i].v] ) {
Tarjan(edge[i].v), low[s] = min(low[s], low[edge[i].v]);
} else if( vis[edge[i].v] ) low[s] = min(low[s], dfn[edge[i].v]);
}
if( dfn[s] == low[s] ) {
col[s] = ++col_num, cnt[col_num] = ;
while( stack[top] != s ) {
col[stack[top]] = col_num, ++cnt[col_num];
vis[stack[top]] = , --top;
}
vis[s] = , --top;
}
} void Deep_fs(int x, int price) {
for(int i = head[x]; i; i = edge[i].nxt) {
cost[edge[i].v] = min(cost[edge[i].v], price);
Deep_fs(edge[i].v, min(cost[edge[i].v], price));
}
} inline void Failed(int x) { printf("NO\n%d\n", x), exit(); } int main(int argc, char const *argv[])
{
freopen("nanjolno.in", "r", stdin);
freopen("nanjolno.out", "w", stdout); int u = , v = , ans = ;
scanf("%d%d", &n, &p);
for(int i = ; i <= p; ++i) buy[i] = read(), val[i] = read();
scanf("%d", &m);
for(int i = ; i <= m; ++i) u = read(), v = read(), Add_edge(u, v);
for(int i = ; i <= n; ++i) if( !dfn[i] ) Tarjan(i); // for(int i = 1; i <= n; ++i) printf("%d ", col[i]);
// printf("\n"); memset(head, , sizeof head), edge_num = ;
for(int i = ; i <= m; ++i)
if( col[edge[i].u] != col[edge[i].v] )
Add_edge(col[edge[i].u], col[edge[i].v]), ++deg[edge[edge_num].v]; // for(int i = 1; i <= col_num; ++i) printf("%d ", deg[i]);
// printf("\n"); memset(cost, 0x3f, sizeof cost);
for(int i = ; i <= p; ++i)
cost[col[buy[i]]] = min(cost[col[buy[i]]], val[i]);
for(int i = ; i <= col_num; ++i)
if( !deg[i] ) Deep_fs(i, cost[i]), ans += cost[i]; // for(int i = 1; i <= col_num; ++i) printf("%d ", cost[i]);
// printf("\n"); for(int i = ; i <= n; ++i)
if( cost[col[i]] == 0x3f3f3f3f ) Failed(i);
printf("YES\n%d\n", ans); fclose(stdin), fclose(stdout);
return ;
}
—— 黑羽《秽翼的尤斯蒂娅》
[Luogu 1262] 间谍网络的更多相关文章
- 洛谷 1262 间谍网络 Tarjan 图论
洛谷 1262 图论 tarjan 并不感觉把这道题目放在图的遍历中很合适,虽然思路比较简单但是代码还是有点多的,, 将可收买的间谍的cost值设为它的价格,不可购买的设为inf,按照控制关系连图,T ...
- luogu P1262 间谍网络
嘟嘟嘟 建图还是很明显的. 接着分两种情况: 1.图中不存在环:那么只要收买那些入度为0的点.如果这些点有的不能收买.就不能控制所有间谍. 2.图中存在环,那么对于这些在环中的点,我们只要收买数额最少 ...
- 【luogu P1262 间谍网络】 题解
题目链接:https://www.luogu.org/problemnew/show/P1262 注意: 1.缩点时计算出入度是在缩完点的图上用color计算.不要在原来的点上计算. 2.枚举出入度时 ...
- Luogu P1262 间谍网络 【强连通分量/缩点】By cellur925
题目传送门 真是一道好题呀~~~~qwq 知道这题是tarjan,但是想了很久怎么用上强连通分量.因为样例们...它显然并不是一个强联通分量! (被样例迷惑的最好例子) 然后...就没有然后了...感 ...
- Luogu P2002 消息扩散&&P1262 间谍网络
怕自己太久没写Tarjan了就会把这种神仙算法忘掉. 其实这种类型的图论题的套路还是比较简单且显然的. P2002 消息扩散 很显然的题目,因为在一个环(其实就是强连通分量)中的城市都只需要让其中一个 ...
- 洛谷 P1262 【间谍网络】
题库 : 洛谷 题号 : 1262 题目 : 间谍网络 link : https://www.luogu.org/problemnew/show/P1262 思路 : 这题可以用缩点的思想来做.先用T ...
- tyvj 1153 间谍网络 tarjan有向图强连通
P1153 - 间谍网络 From ForeverBell Normal (OI)总时限:13s 内存限制:128MB 代码长度限制:64KB 描述 Description 由于外国 ...
- P1262 间谍网络
传送门 思路: ①在 Tarjan 的基础上加一个 belong 记录每个点属于哪个强连通分量. ②存图完成后,暴力地遍历全图,查找是否要间谍不愿受贿. inline void dfs(int u) ...
- [Luogu 2604] ZJOI2010 网络扩容
[Luogu 2604] ZJOI2010 网络扩容 第一问直接最大流. 第二问,添加一遍带费用的边,边权 INF,超级源点连源点一条容量为 \(k\) 的边来限流,跑费用流. 大约是第一次用 nam ...
随机推荐
- js 持续访问保持session对象不消失
$(function(){ publicBusi(); }) //实时刷新登录用户信息 function publicBusi(){ setTimeout(publicBusi,1000*60*10) ...
- 转载 -- CSS3 中关于 select 下拉列表的样式
截图效果:
- .NET提供了三种后台输出js的方式:
.NET提供了三种后台输出js的方式: 首先创建 js文件testjs.js { Page.ClientScript.RegisterClientScriptInclude("keys ...
- javascript帧动画
前面的话 帧动画就是在“连续的关键帧”中分解动画动作,也就是在时间轴的每帧上逐帧绘制不同的内容,使其连续播放而成的动画.由于是一帧一帧的画,所以帧动画具有非常大的灵活性,几乎可以表现任何想表现的内容. ...
- gogs : 添加 ssh An error has occurred : addKey: fail to parse public key: exec: "ssh-keygen": executable file not found in %PATH% - exec: "ssh-keygen": executable file not found in %PATH%
服务器上缺少配置 ssh-keygen.exe的 环境变量.git的环境变量 在path 环境变量加上.重启gogs服务
- MT【285】含参数函数绝对值的最大值
(浙江2013高考压轴题)已知$a\in R$,函数$f(x)=x^3-3x^2+3ax-3a+3$(2)当$x\in[0,2]$时,求$|f(x)|$的最大值. 分析:由题意$f^{'}(x)=3x ...
- python 识别验证码
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/instal ...
- 「UVA10766」Organising the Organisation(生成树计数)
BUPT 2017 Summer Training (for 16) #6C 题意 n个点,完全图减去m条边,求生成树个数. 题解 注意可能会给重边. 然后就是生成树计数了. 代码 #include ...
- selenium的等待~
既然使用了selenium,那么必然牺牲了一些速度上的优势,但由于公司网速不稳定,导致频频出现加载报错,这才意识到selenium等待的重要性. 说到等待又可以分为3类, 1.强制等待 time.sl ...
- Can DBC文件翻译
1 引言 DBC文件描述单个CAN网络的通信.这个信息足以监测和分析网络并模拟不是物理可用的节点(剩余的总线模拟). DBC文件也可以用来开发电子控制单元的通信软件,该控制单元应该是CAN网络的一部分 ...