zoukankan      html  css  js  c++  java
  • hdu 3072 有向图缩点成最小树形图计算最小权

    题意,从0点出发,遍历所有点,遍历边时候要付出代价,在一个SCC中的边不要付费。求最小费用。

    有向图缩点(无需建立新图,,n《=50000,建则超时),遍历边,若不在一个SCC中,用一个数组更新记录最小到达该连通分量的最小边权即可。。。边聊天,边1A,哈哈。。。

    #include<iostream>
    #include<stack>
    #include<queue>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxv=50005,maxe=100005;
    int nume=0;int head[maxv];int e[maxe][3];
    void inline adde(int i,int j,int c)
    {
        e[nume][0]=j;e[nume][1]=head[i];head[i]=nume;
        e[nume++][2]=c;
    }
    int dfn[maxv];int low[maxv];int vis[maxv];int ins[maxv]; stack<int>sta;
    int scc[maxv];int numb=0;int times=0;
    int n,m;
    void tarjan(int u)
    {
        dfn[u]=low[u]=times++;
        ins[u]=1;
        sta.push(u);
        for(int i=head[u];i!=-1;i=e[i][1])
        {
            int v=e[i][0];
            if(!vis[v])
            {
                vis[v]=1;
                tarjan(v);
                if(low[v]<low[u])low[u]=low[v];
            }
            else if(ins[v]&&dfn[v]<low[u])
            {
                low[u]=dfn[v];
            }
        }
        if(low[u]==dfn[u])
        {
            numb++;
            int cur;
           do
            {
                cur=sta.top();
                sta.pop();
                ins[cur]=0;
                scc[cur]=numb;
            }while(cur!=u);
        }
    }
    int mincost_to_v[maxv];    //记录
    void solve()
    {
         vis[0]=1;
         tarjan(0);
        for(int i=0;i<n;i++)
          for(int j=head[i];j!=-1;j=e[j][1])
          {
              int v=e[j][0];
              if(scc[i]!=scc[v])
            {
                if(e[j][2]<mincost_to_v[scc[v]])
                 {
                     mincost_to_v[scc[v]]=e[j][2];
                 }
            }
          }
        int sums=0;
        for(int i=1;i<=numb;i++)
            {
                if(mincost_to_v[i]!=inf)    //起点
                 sums+=mincost_to_v[i];
            }
       printf("%d
    ",sums);
    }
    void read_build()
    {
        int aa,bb,cc;
        for(int i=0;i<m;i++)
        {
            scanf("%d%d%d",&aa,&bb,&cc);
            adde(aa,bb,cc);
        }
    }
    void init()
    {
        numb=times=nume=0;
        for(int i=0;i<maxv;i++)
          {
              head[i]=-1;
              ins[i]=dfn[i]=low[i]=scc[i]=vis[i]=0;
              mincost_to_v[i]=inf;
          }
    }
    int main()
    {
        while(~scanf("%d%d",&n,&m))
        {
            init();
            read_build();
            solve();
        }
        return 0;
    }
    


  • 相关阅读:
    确定方法返回位置为泛型的类型
    centos7 svn服务器搭建
    centos7优化启动项,关闭一些不必要开启的服务
    使用windos电脑模拟搭建集群(四)web环境 linux+nginx+jdk+tomcat
    java使用BeanUtils封装file类型表单数据到一个对象中
    表单隐藏域
    本地yum仓库的搭建
    centos7 挂载exfat格式的u盘
    三体
    海盗分金的故事
  • 原文地址:https://www.cnblogs.com/yezekun/p/3925692.html
Copyright © 2011-2022 走看看