• 洛谷 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
    %d
    ",1);
     96         else printf("YES
    %d
    ",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
    %d
    ",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
    %d
    ",i);return 0;}
    119     printf("YES
    %d
    ",ans);
    120     return 0;
    121 }
    122 
    123 int sb=hh();
    124 int main(int argc,char**argv) {;}
    代码


    作者:乌鸦坐飞机
    出处:http://www.cnblogs.com/whistle13326/
    新的风暴已经出现 怎么能够停止不前 穿越时空 竭尽全力 我会来到你身边 微笑面对危险 梦想成真不会遥远 鼓起勇气 坚定向前 奇迹一定会出现

     
  • 相关阅读:
    如何開始深度學習?
    ckeditor 使用手册
    js 跨域的使用
    关于mysql中数据存储复合树形结构,查询时结果按树形结构输出
    关于tomcat的远程调试
    关于cookie的使用
    关于跨域
    去除除服串中的某些字符,不用String内置方法
    POI导入数据
    onbeforepaste
  • 原文地址:https://www.cnblogs.com/whistle13326/p/7495848.html
Copyright © 2020-2023  润新知