HDU 3072 SCC Intelligence System

给出一个带权有向图,要使整个图连通。SCC中的点之间花费为0,所以就先缩点,然后缩点后两点之间的权值为最小边的权值,把这些权值累加起来就是答案。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 #include <vector>
 6 #include <stack>
 7 using namespace std;
 8 
 9 int n, m;
10 
11 const int maxn = 50000 + 10;
12 
13 vector<int> G[maxn], C[maxn];
14 
15 stack<int> S;
16 int pre[maxn], lowlink[maxn], sccno[maxn];
17 int dfs_clock, scc_cnt;
18 
19 void dfs(int u)
20 {
21     pre[u] = lowlink[u] = ++dfs_clock;
22     S.push(u);
23     for(int i = 0; i < G[u].size(); i++)
24     {
25         int v = G[u][i];
26         if(!pre[v])
27         {
28             dfs(v);
29             lowlink[u] = min(lowlink[u], lowlink[v]);
30         }
31         else if(!sccno[v]) lowlink[u] = min(lowlink[u], pre[v]);
32     }
33 
34     if(lowlink[u] == pre[u])
35     {
36         scc_cnt++;
37         for(;;)
38         {
39             int x = S.top(); S.pop();
40             sccno[x] = scc_cnt;
41             if(x == u) break;
42         }
43     }
44 }
45 
46 void find_scc()
47 {
48     dfs_clock = scc_cnt = 0;
49     memset(pre, 0, sizeof(pre));
50     memset(sccno, 0, sizeof(sccno));
51     for(int i = 0; i < n; i++) if(!pre[i]) dfs(i);
52 }
53 
54 int cost[maxn];
55 
56 int main()
57 {
58     while(scanf("%d%d", &n, &m) == 2)
59     {
60         for(int i = 0; i < n; i++) { G[i].clear(); C[i].clear(); }
61         while(m--)
62         {
63             int u, v, d; scanf("%d%d%d", &u, &v, &d);
64             G[u].push_back(v); C[u].push_back(d);
65         }
66         find_scc();
67 
68         memset(cost, -1, sizeof(cost));
69         for(int i = 0; i < n; i++)
70             for(int j = 0; j < G[i].size(); j++)
71             {
72                 int u = sccno[i], v = sccno[G[i][j]];
73                 if(u == v) continue;
74                 if(cost[v] == -1) cost[v] = C[i][j];
75                 else cost[v] = min(cost[v], C[i][j]);
76             }
77 
78         int ans = 0;
79         for(int i = 1; i <= scc_cnt; i++) if(cost[i] != -1) ans += cost[i];
80         printf("%d\n", ans);
81     }
82 
83     return 0;
84 }
代码君

 

posted @ 2015-08-10 16:10  AOQNRMGYXLMV  阅读(146)  评论(0编辑  收藏  举报