题意:
给出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 }
时间: 2024-10-25 16:09:37