zoukankan      html  css  js  c++  java
  • 【CodeVS4093】EZ的间谍网络

    tarjan缩点,找入度为0的点(可能是一条链的端点或者一个点),入度为0的点必须能被控制。

    每个强连通分量中能被控制的点的最小值是缩点后这个点的最小值,入度为0的点的最小值的和就是最小花费。

    还要记下每个强连通分量中的最小编号,这些编号中的最小值就是第一个不能被控制的点。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 3010
    using namespace std;
    struct edge
    {
        int to,next;
    }e[N*2],d[N*2];
    int head[N],h[N];
    int w[N],W[N];
    bool instack[N];
    int low[N],dfn[N],stack[N];
    int cost[N],MIN[N];
    int belong[N],rudu[N];
    int Index,scc,cnt,top,r;
    int n,p,x,y,u,v;
    void ins(int u,int v)
    {
        e[++cnt].to = v; e[cnt].next = head[u]; head[u] = cnt;
    }
    void tarjan(int k)
    {
        dfn[k] = low[k] = ++Index;
        stack[++top] = k;
        instack[k] = true;
        for (int i=head[k];i;i = e[i].next)
        {
            int v = e[i].to;
            if (instack[v])
                low[k] = min(low[k],dfn[v]);
            else if (!dfn[v])
            {
                tarjan(v);
                low[k] = min(low[k],low[v]);
            }
        }
        if (dfn[k] == low[k])
        {
            scc++;
            int now = 0;
            while (now != k)
            {
                now = stack[top--];
                belong[now] = scc;
                instack[now] = false;
                if (w[now]) 
                {
                    W[scc] = min(W[scc],w[now]);
                }
                MIN[scc] = min(MIN[scc],now);
                
            }
        }
    }
    int main()
    {
        memset(W,127,sizeof(W));
        memset(MIN,127,sizeof(MIN));
        scanf("%d%d",&n,&p);
        for (int i=1;i<=p;i++)
        {
            scanf("%d%d",&x,&y);
            w[x] = y;
        }
        scanf("%d",&r);
        for (int i=1;i<=r;i++)
        {
            scanf("%d%d",&u,&v);
            ins(u,v);
        }
        for (int i=1;i<=n;i++)
            if (!dfn[i])
                tarjan(i);
        cnt = 0;
        for (int i=1;i<=n;i++)
        {
            for (int j = head[i];j;j = e[j].next)
            {
                int v = e[j].to;
                if (belong[i] != belong[v])
                {
                    d[++cnt].to = belong[v];
                    d[cnt].next = h[belong[i]];
                    h[belong[i]] = ++cnt;
                    rudu[belong[v]] ++;
                }
            }
        }
        int pd=0,failmin=6666666,ans = 0;
        for (int i=1;i<=scc;i++)
        {
            if (rudu[i] == 0)
            {
                if (W[i] == 2139062143)
                {
                    pd = 1;
                    failmin = min(failmin,MIN[i]);
                }
                ans += W[i];
            }
        }
        if (pd == 1)
        {
            printf("NO
    ");
            printf("%d",failmin);
            return 0;
        }
        printf("YES
    %d",ans);
    }
  • 相关阅读:
    Java并发编程之volatile变量
    mysql以下c连接mysql数据库
    2014年工作中遇到的20个问题:61-80
    2014年工作中遇到的20个问题:61-80
    雷观(一):我的职业发展路线之一
    雷观(一):我的职业发展路线之一
    CentOS下安装和配置MySQL-JDK-Tomcat-Nginx(个人官网环境搭建手册)
    雷观(序)
    雷观(序)
    ITFriend创业阶段的服务器环境搭建手册
  • 原文地址:https://www.cnblogs.com/liumengyue/p/5598517.html
Copyright © 2011-2022 走看看