zoukankan      html  css  js  c++  java
  • hdu 3072

    强连通分量——tarjin 算法

    这道题和前面那道hdu 2767唯一不同就是,2767需要找出最小数量的边使图成为连通分量,而这个题需要一点点贪心的思想在里面,它需要求出代价最小的边使图成为连通分量;

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <iostream>
     4 #include <stack>
     5 #define N 50006
     6 using namespace std;
     7 
     8 struct Edge
     9 {
    10     int u, val, next;
    11     Edge() {}
    12     Edge(int a, int b, int c)
    13     {
    14         u=a, val=b, next=c;
    15     }
    16 } edge[100006];
    17 
    18 int head[N],tot,n,m,dfn[N],low[N],T,ind,id[N],in[N];
    19 bool vs[N];
    20 stack<int> S;
    21 
    22 void add_edge(int st, int en, int val)
    23 {
    24     edge[tot]=Edge(en,val,head[st]);
    25     head[st]=tot++;
    26 }
    27 
    28 void tarjan(int u)
    29 {
    30     S.push(u), vs[u]=true;
    31     dfn[u]=low[u]=T++;
    32     for(int e=head[u]; e!=-1; e=edge[e].next)
    33     {
    34         int v=edge[e].u;
    35         if(!dfn[v])
    36         {
    37             tarjan(v);
    38             low[u]=min(low[u], low[v]);
    39         }
    40         else if(vs[v] && low[u]>dfn[v]) low[u]=dfn[v];
    41     }
    42     if(low[u]==dfn[u])
    43     {
    44         ind++;
    45         int v;
    46         do
    47         {
    48             v=S.top();
    49             S.pop();
    50             id[v]=ind;
    51             vs[v]=false;
    52         }while(v!=u);
    53     }
    54 }
    55 
    56 int main()
    57 {
    58     while(scanf("%d%d", &n, &m)!=EOF)
    59     {
    60         memset(head, -1, sizeof head);
    61         tot=0;
    62         for(int i=0, a, b, c; i<m; i++)
    63         {
    64             scanf("%d%d%d", &a, &b, &c);
    65             add_edge(a,b,c);
    66         }
    67         while(!S.empty()) S.pop();
    68         memset(vs, 0, sizeof vs);
    69         memset(dfn,0, sizeof dfn);
    70         memset(low,0,sizeof low);
    71         T=ind=0;
    72         for(int i=0; i<n; i++) if(!dfn[i]) tarjan(i);
    73         for(int i=0; i<ind; i++) in[i]=999999;
    74         for(int i=0; i<n; i++)
    75         {
    76             int u=id[i];
    77             for(int e=head[i]; e!=-1; e=edge[e].next)
    78             {
    79                 int v=id[edge[e].u];
    80                 if(u!=v) in[v]=min(in[v], edge[e].val);
    81             }
    82         }
    83         int ans=0;
    84         for(int i=0; i<ind; i++)
    85         {
    86             if(i==id[0]||in[i]==999999) continue;
    87             ans+=in[i];
    88         }
    89         printf("%d
    ", ans);
    90     }
    91     return 0;
    92 }
    View Code
  • 相关阅读:
    十条jQuery代码片段助力Web开发效率提升
    C#如何释放已经加载的图片 (转)
    获取文件夹下最新文件 (转)
    时间格式转换
    调整ListBox控件的行间距及设置文本格式
    c++builder调用vc的dll
    mws文件中的tab文件改为相对路径
    .net 对配置文件内容的操作
    winform下mapxtreme2008 v7.0 生成release版提示找不到dll问题
    vue实现按字母A-Z选择城市
  • 原文地址:https://www.cnblogs.com/yours1103/p/3301907.html
Copyright © 2011-2022 走看看