https://www.luogu.org/problem/show?pid=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:

【样例1】
3
2
1 10
2 100
2
1 3
2 3
【样例2】
4
2
1 100
4 200
2
1 2
3 4
输出样例#1:

【样例1】
YES
110
【样例2】
NO
3 可以先根据间谍关系,然后将能互相指正的人搞到同一个强连通里,
更新出得到收买这群间谍的最小代价,
最后将入度是0的强连通的最小代价统计起来,这样就能收买所有间谍了。
zz如我,更新最小值WA好多次。。
 #include <cstdio>

 const int INF(0x3f3f3f3f);
const int N();
const int M();
int ans,money[N];
int head[N],sumedge;
struct Edge {
int v,next;
inline Edge(int v=,int next=):v(v),next(next){}
}edge[M];
inline void ins(int u,int v)
{
edge[++sumedge]=Edge(v,head[u]);
head[u]=sumedge;
} inline void read(int &x)
{
x=; register char ch=getchar();
for(; ch>''||ch<''; ) ch=getchar();
for(; ch>=''&&ch<=''; ch=getchar()) x=x*+ch-'';
} #define min(a,b) (a<b?a:b) int tim,low[N],dfn[N];
int top,Stack[N],instack[N];
int sumcol,col[N],cmoney[N],rd[N];
void DFS(int u)
{
low[u]=dfn[u]=++tim;
Stack[++top]=u; instack[u]=;
for(int v,i=head[u]; i; i=edge[i].next)
{
v=edge[i].v;
if(!dfn[v]) DFS(v), low[u]=min(low[u],low[v]);
else if(instack[v]) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
col[u]=++sumcol;
for(; Stack[top]!=u; --top)
{
col[Stack[top]]=sumcol;
instack[Stack[top]]=false;
}
top--; instack[u]=false;
}
} int Aptal()
{
// freopen("spyweb.in","r",stdin);
// freopen("spyweb.out","w",stdout); int n,m,p; read(n); read(p);
for(int i=; i<=n; ++i) money[i]=INF;
for(int x,y,i=; i<=p; ++i)
read(x),read(y),money[x]=y;
read(m);
for(int u,v; m--; )
read(u),read(v),ins(u,v);
for(int i=; i<=n; ++i)
if(!dfn[i]&&money[i]!=INF) DFS(i);
for(int i=; i<=n; ++i)
if(!dfn[i])
{
printf("NO\n%d",i);
return ;
}
for(int i=; i<=sumcol; ++i) cmoney[i]=INF;
for(int v,u=; u<=n; ++u)
for(int i=head[u]; i; i=edge[i].next)
{
v=edge[i].v;
if(col[u]!=col[v]) rd[col[v]]++;
}
for(int i=; i<=n; ++i)
cmoney[col[i]]=min(cmoney[col[i]],money[i]);
for(int i=; i<=sumcol; ++i)
if(!rd[i]) ans+=cmoney[i];
printf("YES\n%d",ans);
return ;
} int Hope=Aptal();
int main(){;}

最新文章

  1. 【NLP】基于机器学习角度谈谈CRF(三)
  2. 通过扩展让ASP.NET Web API支持W3C的CORS规范
  3. iOS开源App整理
  4. Android中插件开发篇之----动态加载Activity(免安装运行程序)
  5. 基于WDF的PCI/PCIe接口卡Windows驱动程序(4)- 驱动程序代码(源文件)
  6. JqueryEasyUI中combox的数据不显示
  7. Laravel 5.1 ACL权限控制 四 之middleware
  8. mysql select简单用法
  9. HashMap的遍历和排序
  10. Action、Category、Data、Extras知识具体解释
  11. 如何为ios酷我音乐盒下载导出的音乐文件(使用Java程序设计)
  12. Python笔记4-20151029
  13. ubuntu 14.04 64位安装HTK3.5
  14. 获取select中的值
  15. Thymeleaf入门基础
  16. BBS论坛(八)
  17. VUE开发
  18. 1.5eigen中高级初始化
  19. Docker 安装redis(四)
  20. MySQL -- 外键创建失败

热门文章

  1. wpf Textbox 点击选中全部文本
  2. Intel Media SDK安装步骤
  3. php 0,null,empty,空,false,字符串关系(转)
  4. redis动态添加内存,动态配置,无需重启
  5. k8s Gitlab CI/CD 之自动编译Docker镜像并推送到指定的Registry
  6. BZOJ 1531 二进制优化多重背包
  7. POJ 3258 (NOIP2015 D2T1跳石头)
  8. POJ 1416 DFS
  9. 第5章分布式系统模式 Data Transfer Object(数据传输对象)
  10. C# DataTable常用方法总结