zoukankan      html  css  js  c++  java
  • 洛谷 P1262 间谍网络

    传送门

    题目大意:A能揭发B,B能揭发C..某些人可以被收买,如果收买A,那么A,B,C..的情报都可以得到。

    求能否得到所有情报,如果可以最少花费多少钱去收买。

    题解:tajian缩点

    dfs/bfs从能收买的人遍历图,如果全部都能遍历,那么可以得

    到所有的情报。然后tarjan缩点,并记录缩的每一个点的收买的

    最小值,不能收买的人设收买他的花费是正无穷。统计入度为0

    的点的收买花费和。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 3020
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int n,p,r,sumedge,top,tim,sumclr,cnt,ans,tot;
    int head[maxn],Stack[maxn],instack[maxn],low[maxn];
    int vis[maxn],dfn[maxn],cw[maxn],rd[maxn],w[maxn],bel[maxn];
    
    struct Edge{
        int x,y,nxt;
        Edge(int x=0,int y=0,int nxt=0):
            x(x),y(y),nxt(nxt){}
    }edge[maxn*3];
    
    void add(int x,int y){
        edge[++sumedge]=Edge(x,y,head[x]);
        head[x]=sumedge;
    }
    
    void dfs(int x){
        if(vis[x])return;
        vis[x]=true;++tot;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            dfs(v);
        }
    }
    
    void Tarjian(int x){
        low[x]=dfn[x]=++tim;
        Stack[++top]=x;instack[x]=true;
        for(int i=head[x];i;i=edge[i].nxt){
            int v=edge[i].y;
            if(instack[v])low[x]=min(low[x],dfn[v]);
            else if(!dfn[v]){
                Tarjian(v);low[x]=min(low[x],low[v]);
            }
        }
        if(low[x]==dfn[x]){
            sumclr++;cw[sumclr]=inf;
            while(Stack[top+1]!=x){
                bel[Stack[top]]=sumclr;
                cw[sumclr]=min(cw[sumclr],w[Stack[top]]);
                instack[Stack[top--]]=false;
            }
        }
    }
    
    int main(){
        scanf("%d%d",&n,&p);
        memset(w,0x3f,sizeof(w));
        for(int i=1;i<=p;i++){
            int x,y;
            scanf("%d%d",&x,&y);w[x]=y;
        }
        scanf("%d",&r);
        for(int i=1;i<=r;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            add(a,b);
        }
        for(int i=1;i<=n;i++)if(w[i]!=inf)dfs(i);
        if(tot!=n){
            for(int i=1;i<=n;i++)
             if(vis[i]==0){
                 printf("NO
    ");
                 printf("%d
    ",i);
                 return 0;
             }
        }
        for(int i=1;i<=n;i++)if(!dfn[i])Tarjian(i);
        for(int x=1;x<=n;x++){
            for(int i=head[x];i;i=edge[i].nxt){
                int v=edge[i].y;
                if(bel[x]!=bel[v])rd[bel[v]]++;
            }
        }
        for(int i=1;i<=sumclr;i++)
         if(rd[i]==0)ans+=cw[i];
        printf("YES
    %d
    ",ans);
        return 0;
    }
    AC
  • 相关阅读:
    Docker 部署 ELK 收集 Nginx 日志
    编译安装python3事出错:
    Linux 系统中部署 LNMP 高可用负载均衡架构集群实现动态博客
    [转载]oracle调用JAVA授权问题
    [转载]浏览器跨域
    [转载]ftp和http区别
    [转载]oracle xml操作
    [转载]Oracle中TO_NUMBER()函数的用法
    [转载]桥接与NAT
    [转载]Oracle中动态SQL详解
  • 原文地址:https://www.cnblogs.com/zzyh/p/7711661.html
Copyright © 2011-2022 走看看