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\n", res);

101     }

102     return 0;

103 }

 

你可能感兴趣的:(HDU)