zoukankan      html  css  js  c++  java
  • hdu 3072 强连通+缩点+最小树形图思想

    #include<stdio.h>
    #include<string.h>
    #define N 51000
    #define inf 1000000000
    struct node {
        int u,v,w,next;
    }bian[N*2];
    int dfn[N],low[N],yong,index,ans[N],visit[N],head[N],stac[N],top,num,n;
    void init() {
           yong=0;index=0;top=0;num=0;
            memset(head,-1,sizeof(head));
            memset(dfn,0,sizeof(dfn));
            memset(low,0,sizeof(low));
            memset(visit,0,sizeof(visit));
            memset(stac,0,sizeof(stac));
            memset(ans,0,sizeof(ans));
    }
    void addedge(int u,int v,int w) {
        bian[yong].u=u;
        bian[yong].v=v;
        bian[yong].w=w;
        bian[yong].next=head[u];
        head[u]=yong++;
    }
    int min(int a,int b) {
        return a>b?b:a;
    }
    void tarjan(int u) {//求缩点
        int i;
        dfn[u]=low[u]=++index;
        stac[++top]=u;
        visit[u]=1;
        for(i=head[u];i!=-1;i=bian[i].next) {
            int v=bian[i].v;
            if(!dfn[v]) {
                tarjan(v);
                low[u]=min(low[u],low[v]);
            }
            else
                if(visit[v])
                    low[u]=min(low[u],dfn[v]);
        }
        if(dfn[u]==low[u]) {
            ++num;
            int t;
            do {
                t=stac[top--];
                visit[t]=0;
                ans[t]=num;
            }while(t!=u);
        }
    }
    int main(){
        int m,i,j,k,count,dis[N];
        while(scanf("%d%d",&n,&m)!=EOF) {
                init();
            while(m--) {
                scanf("%d%d%d",&i,&j,&k);
                addedge(i,j,k);
            }
            for(i=0;i<n;i++)
                if(!dfn[i])
                    tarjan(i);
            for(i=1;i<=num;i++)
                dis[i]=inf;
            for(i=0;i<yong;i++)
              if(ans[bian[i].u]!=ans[bian[i].v]) {//找到除源点外的进入每个点的最小权值,所有最小权值的和就是要求的
                  int v=ans[bian[i].v];
                if(dis[v]>bian[i].w)
                    dis[v]=bian[i].w;
            }
            count=0;
            for(i=1;i<=num;i++){
            if(dis[i]<inf)
                count+=dis[i];
            }
            printf("%d
    ",count);
        }
        return 0;
    }
    

  • 相关阅读:
    OpenCV图像处理之 Mat 介绍
    linux 更改网卡名称 eth0
    【git】git常用命令
    【JS】函数提升变量提升以及函数声明和函数表达式的区别
    【VUE】vue中遍历数组和对象
    加密盐的意义和用途
    sql server2005版本中,len函数计算了字符串末尾的空格
    ES之一:API使用及常用概念
    flink (一)
    ClassLoader详解 (JDK9以前)
  • 原文地址:https://www.cnblogs.com/thefirstfeeling/p/4410704.html
Copyright © 2011-2022 走看看