EZ的間諜網絡(codevs 4093)

因爲外國間諜的大量滲入,學校安全正處於高度的危機之中。YJY決定挺身而做出反抗。若是A間諜手中掌握着關於B間諜的犯罪證據,則稱A能夠揭發B。有些間諜收受賄賂,只要給他們必定數量的美圓,他們就願意交出手中掌握的所有情報。因此,若是咱們可以收買一些間諜的話,咱們就可能控制間諜網中的每一分子。由於一旦咱們逮捕了一個間諜,他手中掌握的情報都將歸咱們全部,這樣就有可能逮捕新的間諜,掌握新的情報。ios

  咱們的神通廣大的YJY得到了一份資料,色括全部已知的受賄的間諜,以及他們願意收受的具體數額。同時咱們還知道哪些間諜手中具體掌握了哪些間諜的資料。假設總共有n個間諜(n不超過3000),每一個間諜分別用1到3000的整數來標識。安全

  請根據這份資料,判斷咱們是否有可能控制所有的間諜,若是能夠,求出咱們所須要支付的最少資金。不然,輸出不能被控制的一個間諜。ide

 

輸入描述  Input Description

第一行只有一個整數n。spa

  第二行是整數p。表示願意被收買的人數,1≤p≤n。ip

  接下來的p行,每行有兩個整數,第一個數是一個願意被收買的間諜的編號,第二個數表示他將會被收買的數額。這個數額不超過20000。string

  緊跟着一行只有一個整數r,1≤r≤8000。而後r行,每行兩個正整數,表示數對(A, B),A間諜掌握B間諜的證據。it

 

輸出描述  Output Description

若是能夠控制全部間諜,第一行輸出YES,並在第二行輸出所須要支付的賄金最小值。不然輸出NO,並在第二行輸出不能控制的間諜中,編號最小的間諜編號。io

 

樣例輸入  Sample Input

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

 

 

樣例輸出  Sample Output

【樣例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;
}
View Code
相關文章
相關標籤/搜索