因爲外國間諜的大量滲入,學校安全正處於高度的危機之中。YJY決定挺身而做出反抗。若是A間諜手中掌握着關於B間諜的犯罪證據,則稱A能夠揭發B。有些間諜收受賄賂,只要給他們必定數量的美圓,他們就願意交出手中掌握的所有情報。因此,若是咱們可以收買一些間諜的話,咱們就可能控制間諜網中的每一分子。由於一旦咱們逮捕了一個間諜,他手中掌握的情報都將歸咱們全部,這樣就有可能逮捕新的間諜,掌握新的情報。ios
咱們的神通廣大的YJY得到了一份資料,色括全部已知的受賄的間諜,以及他們願意收受的具體數額。同時咱們還知道哪些間諜手中具體掌握了哪些間諜的資料。假設總共有n個間諜(n不超過3000),每一個間諜分別用1到3000的整數來標識。安全
請根據這份資料,判斷咱們是否有可能控制所有的間諜,若是能夠,求出咱們所須要支付的最少資金。不然,輸出不能被控制的一個間諜。ide
第一行只有一個整數n。spa
第二行是整數p。表示願意被收買的人數,1≤p≤n。ip
接下來的p行,每行有兩個整數,第一個數是一個願意被收買的間諜的編號,第二個數表示他將會被收買的數額。這個數額不超過20000。string
緊跟着一行只有一個整數r,1≤r≤8000。而後r行,每行兩個正整數,表示數對(A, B),A間諜掌握B間諜的證據。it
若是能夠控制全部間諜,第一行輸出YES,並在第二行輸出所須要支付的賄金最小值。不然輸出NO,並在第二行輸出不能控制的間諜中,編號最小的間諜編號。io
【樣例1】class
3stream
2
1 10
2 100
2
1 3
2 3
【樣例2】
4
2
1 100
4 200
2
1 2
3 4
【樣例1】
YES
110
【樣例2】
NO<a name="_GoBack"></a>
3
#include<cstdio> #include<iostream> #include<vector> #include<stack> #include<cstring> #define M 3010 using namespace std; int low[M],num[M],money[M],vis[M],instack[M],belong[M],in[M],out[M],value[M]; int n,cnt,indexx; vector<int> grap[M]; stack<int> s; void tarjan(int v) { low[v]=num[v]=++indexx; vis[v]=1; instack[v]=1; s.push(v); for(int i=0;i<grap[v].size();i++) { int w=grap[v][i]; if(!vis[w]) { tarjan(w); low[v]=min(low[v],low[w]); } else if(instack[w]) low[v]=min(low[v],num[w]); } int u; if(low[v]==num[v]) { cnt++; do { u=s.top(); belong[u]=cnt; if(money[u]) value[cnt]=min(value[cnt],money[u]); s.pop(); instack[u]=0; }while(u!=v); } } int main() { memset(value,0x7f,sizeof(value)); int p,m; scanf("%d%d",&n,&p); for(int i=1;i<=p;i++) { int x,y; scanf("%d%d",&x,&y); money[x]=y; } scanf("%d",&m); for(int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); grap[x].push_back(y); } for(int i=1;i<=n;i++) if(!vis[i]) tarjan(i); for(int i=1;i<=n;i++) for(int j=0;j<grap[i].size();j++) if(belong[i]!=belong[grap[i][j]]) { out[belong[i]]++; in[belong[grap[i][j]]]++; } int ans=0,who=M; for(int i=1;i<=cnt;i++) if(!in[i]) { if(value[i]<=20000) ans+=value[i]; else { for(int j=1;j<=n;j++) if(belong[j]==i) who=min(who,j); } } if(who<M)printf("NO\n%d",who); else printf("YES\n%d",ans); return 0; }