HDU3072

题意:

  给出n个点(0 - n-1),m条边,code从0开始需要传播到1 - (n-1)的每个点,强连通分量之间的传播是没有花费的,求最小花费。

思路:

  缩点,遍历边集,维护两端不属于一个连通分量的边的权和。

  1 #include <bits/stdc++.h>
  2 
  3 const int MAXN = 50000+10;
  4 const int MAXM = 100000+10;
  5 const int INF = 0x3f3f3f3f;
  6  
  7 struct Edge
  8 {
  9     int v, cost, next;
 10     Edge() {}
 11     Edge(int _v, int _cost, int _next):v(_v), cost(_cost), next(_next){}
 12 } edge[MAXM];
 13 int tot;
 14 
 15 int g[MAXN], dfn[MAXN], low[MAXN], T,ind,id[MAXN],dist[MAXN];
 16 
 17 bool vis[MAXN];
 18 std::stack<int> sta;
 19 
 20 void add_edge(int u, int v, int cost)
 21 {
 22     edge[tot] = Edge(v,cost,g[u]);
 23     g[u] = tot++;
 24 }
 25 
 26 void tarjan(int u)
 27 {
 28     sta.push(u);
 29     vis[u] = true;
 30     dfn[u] = low[u] = T++;
 31     for(int i = g[u]; i != -1; i = edge[i].next) {
 32         int v = edge[i].v;
 33         if(!dfn[v]) {
 34             tarjan(v);
 35             low[u] = std::min(low[u], low[v]);
 36         }
 37         else if(vis[v] && low[u] > dfn[v]) 
 38             low[u] = dfn[v];
 39     }
 40     if(low[u] == dfn[u]) {
 41         ind++;
 42         int v;
 43         do {
 44             v=sta.top();
 45             sta.pop();
 46             id[v] = ind;
 47             vis[v] = false;
 48         }while(v != u);
 49     }
 50 }
 51  
 52 void init()
 53 {
 54     memset(g, -1, sizeof g);
 55     memset(vis, 0, sizeof vis);
 56     memset(dfn,0, sizeof dfn);
 57     memset(low,0,sizeof low);
 58     T = ind = tot = 0;
 59     while(sta.empty() == false) 
 60         sta.pop();
 61 }
 62 
 63 int main()
 64 {
 65     int n, m;
 66     while(~scanf("%d%d", &n, &m) ){
 67         init();
 68         for(int i = 0, a, b, c; i<m; i++) {
 69             scanf("%d%d%d", &a, &b, &c);
 70             add_edge(a,b,c);
 71         }
 72 
 73         // get all strongly connected component
 74         // and color them
 75         for(int i = 0; i < n; ++ i){
 76             if(dfn[i] == false){
 77                 tarjan(i);
 78             }
 79         }
 80         // dist[i] is the minimum distance between i and any other point
 81         for(int i = 0; i < ind; i++) {
 82             dist[i] = INF;
 83         }
 84         for(int i = 0; i < n; i++) {
 85             int u = id[i];
 86             for(int e = g[i]; e != -1; e = edge[e].next) {
 87                 int v = id[edge[e].v];
 88                 if(u != v) {
 89                     dist[v] = std::min(dist[v], edge[e].cost);
 90                 }
 91             }
 92         }
 93 
 94         int res = 0;
 95         for(int i = 0; i < ind; ++ i) {
 96             if(i == id[0] || dist[i] == INF)
 97                 continue;
 98             res += dist[i];
 99         }
100         printf("%d
", res);
101     }
102     return 0;
103 }
原文地址:https://www.cnblogs.com/takeoffyoung/p/4607163.html