[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 ...
随机推荐
- Lodop输出页面input文本框的最新值
默认使用Lodop打印页面上的文本框等,会发现虽然页面上文本框输入了值,打印预览却是空的,这是由于没有把最新的值传入Lodop. 如图,演示的是Lodop如何输出文本框内的新值,这里整个页面只有inp ...
- vue axios 封装(二)
封装二: http.js import axios from 'axios' import storeHelper from './localstorageHelper' // 全局设置 const ...
- 关于构造器中的super()
1.为什么在子类的constructor里面要加一句super()? 答:如果子类用了extends的关键字继承的父类,那么子类在使用构造器的时候就要加super()语句,这是语法规范,就是这么定的. ...
- Vue混合mixins
前面的话 本文将详细介绍Vue混合mixins 概述 混合 (mixins) 是一种分发 Vue 组件中可复用功能的非常灵活的方式.混合对象可以包含任意组件选项.以组件使用混合对象时,所有混合对象的选 ...
- 前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构
前后端进行数据交互时候 要优先考虑json格式即简直对形式,[{}] 列表形式 等便于操作的数据结构
- Nginx memcached应用层反向代理
L:105 Module ngx_http_memcached_module 模块默认编译进Nginx
- HTC Vive 基础入门 基于Unreal Engine 4引擎
主要以讲解介绍HTC Vive设备以及Unreal继承的Steam VR Plugin为主 使用最新的虚幻引擎与Plugin完成VR环境的搭建 然后完成一个基本的VR Games. 任务5: 04-配 ...
- HTML元素类别及转换
位置特性分类元素分为三类:块级元素,行内元素,行级块元素 1.块级元素(block) 特点: (1)可以设置宽高.内.外边距: (2)独占一行(即前后均有换行 ...
- POJ 3580-SuperMemo-splay树
很完整的splay操作.做了这题就可以当板子用了. #include <cstdio> #include <algorithm> #include <cstring> ...
- codeforces 242E - XOR on Segment (线段树 按位数建树)
E. XOR on Segment time limit per test 4 seconds memory limit per test 256 megabytes input standard i ...