题目描述
由于外国间谍的大量渗入,国家安全正处于高度的危机之中。如果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,并在第二行输出不能控制的间谍中,编号最小的间谍编号。

输入输出样例
输入
3
2
1 10
2 100
2
1 3
2 3
输出
YES
110


输入
4
2
1 100
4 200
2
1 2
3 4
输出
NO
3


比较模板的一道题了,我们可以先特判输出NO的情况,也就是这个间谍不能被收买,并且其他间谍没有他的证据。


然后就是输出YES的情况了,我们就先缩点,然后入度为0的点中找最小的相加即可。


AC代码:

#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=30010;
int n,p,r,u[N],v[N],vis[N],dfn[N],low[N],cnt,co,col[N],in[N],flag,res;
int head[N],nex[N<<2],to[N<<2],tot,know[N];
stack<int> st;
map<int,int> mp;
inline void add(int a,int b){
	to[++tot]=b; nex[tot]=head[a]; head[a]=tot;
}
void tarjan(int x){
	dfn[x]=low[x]=++cnt;	st.push(x);	vis[x]=1;
	for(int i=head[x];i;i=nex[i]){
		if(!dfn[to[i]]){
			tarjan(to[i]);	low[x]=min(low[x],low[to[i]]);
		}else if(vis[to[i]]) low[x]=min(low[x],dfn[to[i]]);
	}
	if(low[x]==dfn[x]){
		co++;
		while(1){
			int u=st.top();	st.pop();	vis[u]=0;
			col[u]=co;	if(u==x)	break;
		}
	}
}
signed main(){
	cin>>n>>p;
	for(int i=1;i<=p;i++){
		int a,b;	cin>>a>>b;	mp[a]=b;
	}
	cin>>r;
	for(int i=1;i<=r;i++){
		cin>>u[i]>>v[i];	add(u[i],v[i]);	know[v[i]]=1;
	}
	for(int i=1;i<=n;i++)	if(!dfn[i])	tarjan(i);
	for(int i=1;i<=n;i++)	if(!mp[i]&&!know[i])	return printf("NO\n%d\n",i),0;
	for(int i=1;i<=r;i++)	if(col[u[i]]!=col[v[i]])	in[col[v[i]]]++;
	for(int i=1;i<=co;i++){
		if(!in[i]){
			int id=-1;
			for(int j=1;j<=n;j++){
				if(col[j]!=i)	continue;
				if(mp[j]&&(id==-1||mp[j]<mp[id]))	id=j;
			}
			res+=mp[id];	
		}
	}
	printf("YES\n%d\n",res);	
	return 0;
}