洛谷 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:

【样例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

题目并不难 tarjan缩点 建新图 统计入度若只有一个点 即整张图为环 判断是否有人被收买 若有入度为0的点 且没有被收买 则为NO从入度为0的点遍历新图 若有点没有遍历到 则为NO否则为YES

  1 #include <queue>
  2 #include <cstdio>
  3 #include <cctype>
  4 #include <cstring>
  5
  6 const int INF=0x3f3f3f3f;
  7 const int MAXN=3010;
  8 const int MAXM=8010;
  9
 10 int n,p,r,inr,id,ans,top;
 11
 12 int fee[MAXN],dfn[MAXN],low[MAXN],stack[MAXN],belong[MAXN],Money[MAXN],In[MAXN];
 13
 14 bool vis[MAXN];
 15
 16 struct node {
 17     int to;
 18     int next;
 19     node() {}
 20     node(int to,int next):to(to),next(next) {}
 21 };
 22 node e[MAXN<<1],Edge[MAXN<<1];
 23
 24 int head[MAXN],tot,Head[MAXN],TOT;
 25
 26 inline void read(int&x) {
 27     int f=1;register char c=getchar();
 28     for(x=0;!isdigit(c);c==‘-‘&&(f=-1),c=getchar());
 29     for(;isdigit(c);x=x*10+c-48,c=getchar());
 30     x=x*f;
 31 }
 32
 33 inline int min(int a,int b) {return a<b?a:b;}
 34
 35 inline bool pd(int u,int v) {
 36     for(int i=Head[u];i;i=Edge[i].next) if(v==Edge[i].to) return true;
 37     return false;
 38 }
 39
 40 inline void add(int x,int y) {
 41     e[++tot]=node(y,head[x]);
 42     head[x]=tot;
 43 }
 44
 45 void tarjan(int u) {
 46     dfn[u]=low[u]=++inr;
 47     stack[++top]=u;
 48     vis[u]=true;
 49     for(int i=head[u];i;i=e[i].next) {
 50         int v=e[i].to;
 51         if(!dfn[v]) {
 52             tarjan(v);
 53             low[u]=min(low[u],low[v]);
 54         }
 55         else if(vis[v]) low[u]=min(low[u],dfn[v]);
 56     }
 57     if(dfn[u]==low[u]) {
 58         ++id;
 59         int t;
 60         do {
 61             t=stack[top--];
 62             if(fee[t]) Money[id]=min(Money[id],fee[t]);
 63             vis[t]=false;
 64             belong[t]=id;
 65         }while(u!=t);
 66     }
 67 }
 68
 69 inline void build_NEW() {
 70     memset(vis,false,sizeof vis);
 71     for(int i=1;i<=n;++i)
 72       for(int j=head[i];j;j=e[j].next) {
 73           int v=e[j].to;
 74           if(belong[i]==belong[v]) continue;
 75           if(pd(belong[i],belong[v])) continue;
 76           ++In[belong[v]];
 77           Edge[++TOT]=node(belong[v],Head[belong[i]]);
 78           Head[belong[i]]=TOT;
 79       }
 80     return;
 81 }
 82
 83 int hh() {
 84     read(n);read(p);
 85     for(int x,y,i=1;i<=p;++i) read(x),read(y),fee[x]=y;
 86     read(r);
 87     for(int x,y,i=1;i<=r;++i) {
 88         read(x);read(y);
 89         add(x,y);
 90     }
 91     memset(Money,INF,sizeof Money);
 92     for(int i=1;i<=n;++i)
 93       if(!dfn[i]) tarjan(i);
 94     if(id==1) {
 95         if(Money[1]==INF) printf("NO\n%d\n",1);
 96         else printf("YES\n%d\n",Money[1]);
 97         return 0;
 98     }
 99     build_NEW();
100     for(int i=1;i<=n;++i)
101       if(!In[belong[i]]&&Money[belong[i]]==INF) {
102           printf("NO\n%d\n",i);
103           return 0;
104       }
105     std::queue<int> q;
106     for(int i=1;i<=id;++i) if(!In[i]&&Money[i]) q.push(i),vis[i]=true,ans+=Money[i];
107     while(!q.empty()) {
108         int u=q.front();
109         q.pop();
110         for(int i=Head[u];i;i=Edge[i].next) {
111             int v=Edge[i].to;
112             if(!vis[v]) {
113                 vis[v]=true;
114                 q.push(v);
115             }
116         }
117     }
118     for(int i=1;i<=n;++i) if(!vis[belong[i]]) {printf("NO\n%d\n",i);return 0;}
119     printf("YES\n%d\n",ans);
120     return 0;
121 }
122
123 int sb=hh();
124 int main(int argc,char**argv) {;}

代码

时间: 2024-10-12 21:19:38

洛谷 P1262 间谍网络的相关文章

洛谷——P1262 间谍网络

P1262 间谍网络 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关提供了一份资料,色括所有已知的受贿的间谍,以及他们愿意收受的具体数额.同时我们还知道哪些

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

4093 EZ的间谍网络 时间限制: 10 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关

洛谷P1262 间谍网络

本来只想刷道小题,没想到还有点麻烦 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关提供了一份资料,色括所有已知的受贿的间谍,以及他们愿意收受的具体数额.同时

洛谷 P1262 间谍网络 Label: Kosarajn说:我就是不用Tarjan &amp;&amp; Tarjan待做

题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关提供了一份资料,色括所有已知的受贿的间谍,以及他们愿意收受的具体数额.同时我们还知道哪些间谍手中具体掌握了哪些

tarjan缩点以及链式前向星的基本+应用(洛谷1262 间谍网络)

题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A可以揭发B.有些间谍收受贿赂,只要给他们一定数量的美元,他们就愿意交出手中掌握的全部情报.所以,如果我们能够收买一些间谍的话,我们就可能控制间谍网中的每一分子.因为一旦我们逮捕了一个间谍,他手中掌握的情报都将归我们所有,这样就有可能逮捕新的间谍,掌握新的情报. 我们的反间谍机关提供了一份资料,色括所有已知的受贿的间谍,以及他们愿意收受的具体数额.同时我们还知道哪些间谍手中具体掌握了哪些

[luogu]P1262 间谍网络 题解

原题目:[luogu]P1262 间谍网络 数据范围好小啊(小声) 首先对于环 , 我们可以直接缩成点 , 如果环上的有好多可以收买的间谍的话就找其中要价最低的作为这个缩点后的点的要价 然后怎么处理呐? 我做完以后看到题解区有神仙一个循环就能处理出答案 但是我太菜了自己做的时候并没有想到qaq 所以就用了 DFS 再建一个缩点后的图 , 然后从每一个可以被收买的点上 DFS , 最后看看有没有点没有被搜到就可以了 如果说从一个可以被收买的点 a , 搜的时候找到了另一个已经搜过而且也是可以被收买

洛谷 P2038 无线网络发射器选址(NOIp2014D2T1)

题目描述 随着智能手机的日益普及,人们对无线网的需求日益增大.某城市决定对城市内的公共场所覆盖无线网. 假设该城市的布局为由严格平行的129 条东西向街道和129 条南北向街道所形成的网格状,并且相邻的平行街道之间的距离都是恒定值 1 .东西向街道从北到南依次编号为0,1,2-128 , 南北向街道从西到东依次编号为0,1,2-128 . 东西向街道和南北向街道相交形成路口,规定编号为x 的南北向街道和编号为y 的东西向街道形成的路口的坐标是(x , y ). 在 某 些 路口存在一定数量的公共

洛谷 P1546 最短网络 Agri-Net Label:Water最小生成树

题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 题目描述 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最小的消费,他想铺设最短的光纤去连接所有的农场. 你将得到一份各农场之间连接费用的列表,你必须找出能连接所有农场并所用光纤最短的方案.每两个农场间的距离不会超过100000 输入输出格式 输入格式: 第一行: 农场的个数,N(3<=N<=100). 第二行..结尾: 后来的行包含了一

洛谷P1546 最短网络 Agri-Net

P1546 最短网络 Agri-Net 526通过 959提交 题目提供者JOHNKRAM 标签图论贪心USACO 难度普及/提高- 提交该题 讨论 题解 记录 最新讨论 50分C++代码,求解 请指教哪里出现了问题,只有… 求解为什么只有40分 题目背景 农民约翰被选为他们镇的镇长!他其中一个竞选承诺就是在镇上建立起互联网,并连接到所有的农场.当然,他需要你的帮助. 题目描述 约翰已经给他的农场安排了一条高速的网络线路,他想把这条线路共享给其他农场.为了用最小的消费,他想铺设最短的光纤去连接所