思路 :

这题可以用缩点的思想来做。先用Tarjan算法以一个没有被搜过&&能被收贿赂的点为起点,把每个强连通分量给缩成一个点(一个强连通分量 )(这个强连通分量里的任意一个可以收贿赂的间谍 收贿赂之后,就可以 掌握这个强连通分量中其他间谍的证据),然后我们在搜Tarjan 的时候记得把每个强连通分量中的最小收贿赂值算出来,这个对以后计算答案很有帮助。

最后就剩下两点了:

  1. 可以掌握所有间谍的证据 : 这个情况是因为搜完Tarjan之后,所有点都在强连通分量里(至于在哪个无所谓,反正都在强连通分量里)。那 么我们只需要把入度为0的强连通分量中的最小收贿赂 值加起来就好了(如果入度不为0,那么这个强连通分量就可以被其他强连通分 量中的间谍掌握证据,这样这个强连通分量就都可以不用收贿赂就被掌握证据了)
  2. 不能掌握所有间谍的证据 : 这个情况是因为当我们搜完Tanjan之后,如果有一个点(间谍)没有被搜到过,他就无法被掌握证据(他不在任何 一个强连通分量中,他既无法被收贿赂,也无法被其 他能收贿赂的间谍掌握证据)。

注意 :

你可能会怀疑一个强连通分量中没有任何一个间谍可以收贿赂,当然,这种情况是有的。但如果一个强连通分量被搜到了&&他里面没有可以收 贿赂的间谍,既然他被搜到了,那么一定有一个可以 收贿赂的间谍出   发,最后搜到了当前强连通分量(这个强连通分量的入度肯定不为0, 所以这个担心是多余的)


解释一下样例:


code :

 #include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
stack < int > pru;
int n, m, M, q[], dfn[], low[], vis[], col[], head[], minn[], in[], color, num, z, ans;
struct node
{
int next, to;
}stu[];
inline void add(int x, int y)//链表存图
{
stu[++num].next = head[x];
stu[num].to = y;
head[x] = num;
return;
}
inline void tarjan(int u)//Tarjan模板
{
dfn[u] = low[u] = ++z;
vis[u] = ;
pru.push(u);
for(register int i = head[u]; i; i = stu[i].next)
{
int k = stu[i].to;
if(!vis[k])
{
tarjan(k);
low[u] = min(low[u], low[k]);
}
else if(!col[k])
{
low[u] = min(low[u], dfn[k]);
}
}
if(dfn[u] == low[u])
{
col[u] = ++color;
minn[color] = min(minn[color], q[u]);//在一个强连通分量中,寻找其中可以贿赂的最小值
while(pru.top() != u)
{
col[pru.top()] = color;
minn[color] = min(minn[color], q[pru.top()]);//同理
pru.pop();
}
pru.pop();
}
return;
}
signed main()
{
memset(minn, INF, sizeof(minn));//初始化为最大
memset(q, INF, sizeof(q));//同理
scanf("%d %d", &n, &M);
for(register int i = , x, y; i <= M; ++i)
{
scanf("%d %d", &x, &y);
q[x] = y;
}
scanf("%d", &m);
for(register int i = , x, y; i <= m; ++i)
{
scanf("%d %d", &x, &y);
add(x, y);
}
for(register int i = ; i <= n; ++i)
{
if(!vis[i] && q[i] != INF)//要判断这人是否可以贿赂
{
tarjan(i);
}
}
for(register int i = ; i <= n; ++i)
{
if(!vis[i])//如果有人没被搜到过(及无法掌握这人的证据)
{
printf("NO\n%d", i);//由于是从小到大(1 ~ n),所以第一个搜到没被搜过的就是最小值
return ;
}
}
for(register int u = ; u <= n; ++u)
{
for(register int i = head[u]; i; i = stu[i].next)//寻找其中入度为0的点
{
int k = stu[i].to;
if(col[k] != col[u])//颜色不同(及不在一个强连通分量中)
{
++in[col[k]];//k所在的强连通分量的入度++
}
}
}
for(register int i = ; i <= color; ++i)//枚举每个强连通分量
{
if(!in[i])//没有入度(不能被其他强连通分量中的间谍掌握证据)
{
ans += minn[i];//这个点中可收贿赂最小的间谍就必须贿赂他
}
}
printf("YES\n%d", ans);
return ;
}

洛谷 P1262 【间谍网络】的更多相关文章

  1. 【题解】洛谷P1262 间谍网络 (强连通分量缩点)

    洛谷P1262:https://www.luogu.org/problemnew/show/P1262 思路 一看题目就知道是强连通分量缩点 当图中有强连通分量时 将其缩点 我们可以用dfn数组判断是 ...

  2. 洛谷——P1262 间谍网络

    P1262 间谍网络 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意 ...

  3. 洛谷 P1262 间谍网络==Codevs 4093 EZ的间谍网络

    4093 EZ的间谍网络 时间限制: 10 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B ...

  4. 洛谷P1262 间谍网络[强连通分量 BFS]

    题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报 ...

  5. 洛谷 P1262 间谍网络 Label: Kosarajn强联通

    题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报 ...

  6. 洛谷P1262 间谍网络

    本来只想刷道小题,没想到还有点麻烦 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美 ...

  7. 洛谷P1262间谍网络

    题目 我们首先考虑该题没有环应该怎么做,因为没有环所以是一个DAG,因此直接加上入度为0的罪犯,而有环则可以缩点,之后就成为了DAG,然后用一方法做就好了. \(Code\) #include < ...

  8. 洛谷 P1262 间谍网络 —— 缩点

    题目:https://www.luogu.org/problemnew/show/P1262 首先,一个强连通分量里有一个点被控制则所有点都被控制,所以先 tarjan 缩点,记一下每个连通块中能被收 ...

  9. 洛谷—— P1262 间谍网络

    https://www.luogu.org/problem/show?pid=1262 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A ...

  10. 洛谷 P1262 间谍网络

    传送门 题目大意:A能揭发B,B能揭发C..某些人可以被收买,如果收买A,那么A,B,C..的情报都可以得到. 求能否得到所有情报,如果可以最少花费多少钱去收买. 题解:tajian缩点 dfs/bf ...

随机推荐

  1. [POJ2823] Sliding Window 「单调队列」

    我们从最简单的问题开始: 给定一个长度为N的整数数列a(i),i=0,1,...,N-1和窗长度k. 要求:   f(i) = max{ a(i-k+1),a(i-k+2),..., a(i) },i ...

  2. spring aop(四)

    直接找到解析aop标签的方法: protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate deleg ...

  3. Java 第四章

    switch选择结构 语法:switch(表达式){ case 常量 1: //代码块1:   break:  case 常量 2: //代码块2: break:    ......  default ...

  4. 【Java】判断字符串是否含字母

    用正则表达式,示例代码如下: String str = "123abc"; Pattern.compile("(?i)[a-z]]").matcher(str) ...

  5. 自定义SWT控件三之搜索功能下拉框

    3.搜索功能下拉弹出框 package com.view.control.select; import java.util.ArrayList; import java.util.LinkedList ...

  6. .net core 基于 IHostedService 实现定时任务

    .net core 基于 IHostedService 实现定时任务 Intro 从 .net core 2.0 开始,开始引入 IHostedService,可以通过 IHostedService ...

  7. TextView 使用详解

    极力推荐文章:欢迎收藏 Android 干货分享 阅读五分钟,每日十点,和您一起终身学习,这里是程序员Android 本篇文章主要介绍 Android 开发中的部分知识点,通过阅读本篇文章,您将收获以 ...

  8. 【React踩坑记三】React项目报错Can't perform a React state update on an unmounted component

    意思为:我们不能在组件销毁后设置state,防止出现内存泄漏的情况 分析出现问题的原因: 我这里在组件加载完成的钩子函数里调用了一个EventBus的异步方法,如果监听到异步方法,则会更新state中 ...

  9. 【Java例题】5.5 映射类的使用

    5.映射类的使用.使用HashMap保存英文-中文对照单词词典.单词词典可以增加和删除词汇.输入一个英文单词,翻译成中文并显示.输入一个中文单词,翻译成英文并显示. package chapter6; ...

  10. Spring文档学习

    Spring文档学习 参考Spring Framework Documentation学习 1. IoC 容器 1.1 容器实例化 <beans> <import resource= ...