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

    https://loj.ac/problem/10095

    题目描述

      有n个间谍,每个间谍手里有其他间谍的资料,有p个间谍愿意被收买,问能否获得所有间谍的资料,能,就输出最小花费,否则输出不能被控制的间谍中编号最小的一个。

    思路

      如果间谍手中的资料形成一个环,我们就只需要收买这个环上原因被收买的最小金额的人。因此我们可以缩点,缩点后的点权即为强连通分量中愿意被收买的间谍的最小金额。所以对于缩点后的DAG,我们只需要考虑入度为0的点,因为若入度为0的点必须收买,否则就无法获得它的资料,而收买其他点必定会使总花费增加。而如果不能得到所有资料,那么不能控制的间谍有两种可能:①入度为0且不能被收买;②入度为1且由第一种可能中的人转移过来。我们只需要统计这当中编号最小的即可。

    #include <bits/stdc++.h>
    using namespace std;
    const int N=3300,M=8800;
    
    struct Edge
    {
        int x,y;
    }e[M];
    
    int nxt[M],head[N],to[M],tot;
    void add_edge(int x,int y)
    {
        nxt[++tot]=head[x];
        head[x]=tot;
        to[tot]=y;
        e[tot].x=x;e[tot].y=y;
    }
    
    int read()
    {
        int res=0,w=1;
        char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
        while(ch>='0'&&ch<='9'){res=(res<<3)+(res<<1)+ch-'0';ch=getchar();}
        return res*w;
    }
    
    int dfn[N],low[N],st[N],co[N],cc[N],top,idx,col,v[N];
    void tarjan(int u)
    {
        dfn[u]=low[u]=++idx;
        st[++top]=u;
        for(int i=head[u];i;i=nxt[i])
        {
            int v=to[i];
            if(!dfn[v])
            {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else if(!co[v])
                low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u])
        {
            co[u]=++col;
            while(st[top]!=u)
            {
                co[st[top]]=col;
                --top;
            }
            --top;
        }
    }
    
    int in[N];
    int main() 
    {
        int n,p,r;
        n=read();p=read();
        for(int i=1;i<=p;i++)
        {
            int x=read();
            v[x]=read();
        }
        r=read();
        for(int i=1;i<=r;i++)
        {
            int a=read(),b=read();
            add_edge(a,b);
        }
        for(int i=1;i<=n;i++)
            if(!dfn[i])tarjan(i);
        for(int i=1;i<=r;i++)
        {
            int u=co[e[i].x],v=co[e[i].y];
            if(u!=v)
                in[v]++;
        }
        int ans=0,cnt=0;
        for(int i=1;i<=n;i++)
            if(!in[co[i]])
            {
                if(v[i]==0)
                {
                    cnt=cnt==0?i:min(cnt,i);    //情况1 
                    for(int j=head[i];j;j=nxt[j])
                        if(j<cnt&&!v[i]&&in[co[j]]==1)//情况2 
                            cnt=j;
                }
                else
                    ans+=v[i];
            }
        if(cnt==0)printf("YES
    %d",ans);
        else printf("NO
    %d",cnt);
    }
  • 相关阅读:
    form表单提交target属性使用
    window.showModalDialog
    mybaits中date类型显示时分秒(orcle数据库)
    mybatis中in查询
    偷懒的inline-block解决方法
    10. python单元测试(一)
    9. Request & 爬虫
    8. 类与对象
    7. python异常处理&异常基类学习
    6. IO及文件操作
  • 原文地址:https://www.cnblogs.com/fangbozhen/p/11728561.html
Copyright © 2011-2022 走看看