TYVJ P1153 间谍网络

P1153 间谍网络
时间: 1000ms / 空间: 131072KiB / Java类名: Main

描述

由于外国间谍的大量渗入,国家安全正处于高度危机之中。如果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

输入



2 512 

1 2 
2 1

输出

YES 
512

 

解题:强连通缩点,看看入度为0 的强连通块中哪个最小选哪个。。。

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 4000;
 4 const int INF = 0x3f3f3f3f;
 5 struct arc {
 6     int to,next;
 7     arc(int x = 0,int y = -1) {
 8         to = x;
 9         next = y;
10     }
11 } e[500000];
12 int head[maxn],dfn[maxn],low[maxn],belong[maxn];
13 int minV[maxn],value[maxn],in[maxn],tot,idx,scc,n,m;
14 bool instack[maxn];
15 stack<int>stk;
16 void init() {
17     for(int i = 0; i < maxn; ++i) {
18         dfn[i] = low[i] = head[i] = -1;
19         instack[i] = false;
20         minV[i] = value[i] = INF;
21         in[i] = belong[i] = 0;
22     }
23     tot = scc = idx = 0;
24     while(!stk.empty()) stk.pop();
25 }
26 void add(int u,int v) {
27     e[tot] = arc(v,head[u]);
28     head[u] = tot++;
29 }
30 void tarjan(int u) {
31     dfn[u] = low[u] = ++idx;
32     instack[u] = true;
33     stk.push(u);
34     for(int i = head[u]; ~i; i = e[i].next) {
35         if(dfn[e[i].to] == -1) {
36             tarjan(e[i].to);
37             low[u] = min(low[u],low[e[i].to]);
38         } else if(instack[e[i].to]) low[u] = min(low[u],dfn[e[i].to]);
39     }
40     if(low[u] == dfn[u]) {
41         scc++;
42         int v;
43         do {
44             instack[v = stk.top()] = false;
45             stk.pop();
46             belong[v] = scc;
47         } while(v != u);
48     }
49 }
50 int main() {
51     int u,v,w;
52     while(~scanf("%d",&n)) {
53         init();
54         scanf("%d",&m);
55         for(int i = 1; i <= m; ++i) {
56             scanf("%d %d",&u,&w);
57             value[u] = w;
58         }
59         scanf("%d",&m);
60         while(m--) {
61             scanf("%d %d",&u,&v);
62             add(u,v);
63         }
64         for(int i = 1; i <= n; ++i)
65             if(dfn[i] == -1) tarjan(i);
66         int ans = 0;
67         for(int i = 1; i <= n; ++i) {
68             minV[belong[i]] =  min(minV[belong[i]],value[i]);
69             for(int j = head[i]; ~j; j = e[j].next) {
70                 if(belong[i] != belong[e[j].to]) in[belong[e[j].to]]++;
71                 minV[belong[e[j].to]] = min(minV[belong[e[j].to]],value[e[j].to]);
72             }
73         }
74         for(int i = 1; i <= scc; ++i)
75             if(!in[i]) {
76                 if(minV[i] == INF) {
77                     ans = INF;
78                     break;
79                 }
80                 ans += minV[i];
81             }
82         if(ans < INF) printf("%s\n%d\n","YES",ans);
83         else{
84             for(int i = 1; i <= n; ++i)
85             if(in[belong[i]] == 0 && minV[belong[i]] == INF && value[i] == INF){
86                 ans = i;
87                 break;
88             }
89             printf("%s\n%d\n","NO",ans);
90         }
91     }
92     return 0;
93 }
View Code

 

posted @ 2015-04-02 19:26  狂徒归来  阅读(273)  评论(0编辑  收藏  举报