zoukankan      html  css  js  c++  java
  • hdoj1827

    图的强连通,缩点,求个入度为0的点的数量,和入度为0的点集里面最小的花费和。
    //很死板的题,模板题的一样的…

    #include<cstdio>
    #include<queue>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    #define INF 9999999
    #define mod 1000000007
    #define N 1050
    typedef long long LL;
    
    struct asd{
        int to;
        int next;
    };
    asd q[N*2];
    int head[N*2];
    int tol;
    
    int low[N];
    int dfn[N];
    bool vis[N];
    int n,m;
    int sta[N];
    int cost[N];
    int in[N];
    int incos[N];
    int ru[N];
    int tp,p;
    int sum;
    
    void tarjan(int u)
    {
        dfn[u]=low[u]=++tp;
        sta[++p]=u;
        vis[u]=1;
    
        for(int k=head[u];k!=-1;k=q[k].next)
        {
            int i=q[k].to;
            if(!dfn[i])
            {
                tarjan(i);
                low[u]=min(low[i],low[u]);
            }
            else if(vis[i])
            {
                low[u]=min(low[u],dfn[i]);  
            }
        }
        if(dfn[u]==low[u])
        {
            ++sum;
            int temp;
            while(1)
            {
                temp=sta[p];
                vis[temp]=0;
                in[temp]=sum;
                incos[sum]=min(incos[sum],cost[temp]);
                p--;
                if(temp==u)
                {
                    break;
                }
    
            }
        }
    }
    
    void solve_rudu()
    {
        memset(ru,0,sizeof(ru));
    
        for(int i=1;i<=n;i++)
        {
            for(int k=head[i];k!=-1;k=q[k].next)
            {
                int ss=q[k].to;
                if(in[ss]!=in[i])
                    ru[in[ss]]++;
            }
        }
        int ans=0;
        int ccs=0;
        for(int i=1;i<=sum;i++)
        {
            if(!ru[i])
            {
                ans++;
                ccs+=incos[i];
            }
        }
        printf("%d %d
    ",ans,ccs);
    }
    
    void init()
    {
        tol=0;
        memset(dfn,0,sizeof(dfn));
        memset(head,-1,sizeof(head));
        memset(vis,0,sizeof(vis));
        memset(incos,INF,sizeof(incos));
    }
    
    void add(int a,int b)
    {
        q[tol].to=b;
        q[tol].next=head[a];
        head[a]=tol++;
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&cost[i]);
            }
            init();
            for(int i=0;i<m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                add(a,b);
            }
            sum=tp=p=0;
            for(int i=1;i<=n;i++)
            {
                if(!dfn[i])
                {
                    tarjan(i);
                }
            }
            solve_rudu();       
        }
    }
  • 相关阅读:
    Solr的配置和在java中的使用
    druid + mysql + mybatis 批量更新报错
    linux find命令-print0和xargs中-0使用技巧
    Shell 函数相关
    公钥、私钥和数字签名这样最好理解
    Liunx find/locate/whereis/which 总结
    Linux find命令
    Shell bash 数学运算 bc
    Shell 使用 expr 进行数学运算
    Shell 有类型变量
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934520.html
Copyright © 2011-2022 走看看