HDU 3072 Intelligence System(最小樹形圖+Tarjan)__最小樹形圖

來源:互聯網
上載者:User

題目連結:
HDU 3072 Intelligence System
題意:
n個點編號從0–n-1,根節點編號為0,m條有向邊,屬於同一有向環中的邊權為0,求從根節點能到達其餘所有點的最小花費。
分析:
屬於同一強連通分量中邊權為0.先用Tanjan演算法將同一有向環中的點重新編號,然後將所有邊的頂點重新編號,
並判斷是否屬於同一強連通分量,最後再跑一遍最小樹形圖即可。

#include <iostream>#include <cstdio>#include <cstring>#include <string>#include <algorithm>#include <climits>#include <cmath>#include <ctime>#include <cassert>#include <vector>#include <stack>#define IOS ios_base::sync_with_stdio(0); cin.tie(0);using namespace std;typedef long long ll;typedef pair<int, ll> pii;const int MAX_N = 50010;const int MAX_M = 100010;int n, m, dfs_clock, scc_cnt;int pre[MAX_N], In[MAX_N], ID[MAX_N], vis[MAX_N], low[MAX_N], sccno[MAX_N];vector <int> G[MAX_N];stack<int> S;struct Edge{    int u, v, w;}edge[MAX_M];void init(){    scc_cnt = dfs_clock = 0;    for(int i = 0; i <= n; i++){        G[i].clear();    }    while(!S.empty()) S.pop();    memset(sccno, -1, sizeof(sccno));    memset(pre, -1, sizeof(pre));}void dfs(int u){    pre[u] = low[u] =dfs_clock++;    S.push(u);    for(int i = 0; i < G[u].size(); i++){        int v = G[u][i];        if(pre[v] == -1){            dfs(v);            low[u] = min(low[u], low[v]);        }else if(sccno[v] == -1){            low[u] = min(low[u], pre[v]);        }    }    if(low[u] == pre[u]){        while(1){            int x = S.top();            S.pop();            sccno[x] = scc_cnt;            if(x == u) break;        }        scc_cnt++;    }}void find_scc(){    for(int i = 0; i < n; i++){        if(pre[i] == -1) dfs(i);    }}int ZLEdmonds(int root, int NV, int NE){    int res = 0, w, u, v;    while(1){        for(int i = 0; i < NV; i++) { In[i] = INT_MAX; }        for(int i = 0; i < NE; i++){            u = edge[i].u, v = edge[i].v, w = edge[i].w;            if(u != v && w < In[v]){                In[v] = w;                pre[v] = u;            }        }        int cnt = 0;        memset(vis, -1, sizeof(vis));        memset(ID, -1, sizeof(ID));        In[root] = 0;        for(int i = 0; i < NV; i++){            res += In[i];            v = i;            while(v != root && ID[v] == -1 && vis[v] != i){                vis[v] = i;                v = pre[v];            }            if(v != root && ID[v] == -1){                for(u = pre[v]; u != v; u = pre[u]){                    ID[u] = cnt;                }                ID[v] = cnt++;            }        }        if(cnt == 0) break;        for(int i = 0; i < NV; i++){            if(ID[i] == -1) ID[i] = cnt++;        }        for(int i = 0; i < NE; i++){            u = edge[i].u, v = edge[i].v, w = edge[i].w;            edge[i].u = ID[u], edge[i].v = ID[v];            if( edge[i].u != edge[i].v){                edge[i].w -= In[v];            }        }        NV = cnt, root = ID[root];    }     return res;}int main(){    while(~scanf("%d%d", &n, &m)){        init();        for(int i = 0; i < m; i++){            scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);            G[edge[i].u].push_back(edge[i].v);        }        find_scc();        for(int i = 0; i < m; i++){            int u, v;            u = edge[i].u, v = edge[i].v;            edge[i].u = sccno[u], edge[i].v = sccno[v];            if(edge[i].u == edge[i].v){                edge[i].w = 0;            }        }        int root = sccno[0];        int ans = ZLEdmonds(root, scc_cnt, m);        printf("%d\n", ans);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.