UVa 12587 Reduce the Maintenance Cost(Tarjan + 二分 + DFS),12587tarjan

來源:互聯網
上載者:User

UVa 12587 Reduce the Maintenance Cost(Tarjan + 二分 + DFS),12587tarjan

題意:n個城市(n <= 10000), 有m條邊(m <= 40000),每個城市有一個維護費用Cost(i),除此之外,每條邊的維修費用為去掉該邊後不能通訊的城市對數與邊權的積,這個費用要加到這條邊的兩端城市的某一個,問你所有城市的最大費用的最小值。、

思路:首先邊的費用可以通過Tarjan求橋之後求得(利用橋的性質),然後就是二分答案了!對於每個點,如果有個兒子不能維護,那麼不可行,否則,試著讓兒子去維護邊權,如果不可行,只能讓父親承擔。

#include <iostream>#include <cstdio>#include <cstring>#include <vector>#include <string>#include <algorithm>#include <queue>#include <set>#include <map>using namespace std;typedef long long LL;const int maxn = 10000+10;const int maxm = 40000+10;LL cost[maxn];int head[maxn];int n,m;int dfn[maxn],lown[maxn];bool CanE[maxn];int cnt[maxm];LL ans;int nume,dfs_clock;bool vis[maxn];bool isBridge[maxm];vector<int> sta;struct edge{    int u,v,w,nxt;}e[maxm];void Tarjan(int u,int fa) {    lown[u] = dfn[u] = dfs_clock++;    sta.push_back(u);    for(int i = head[u]; i ; i = e[i].nxt) {        int v = e[i].v;        if(v==fa) continue;        if(!dfn[v]) {            Tarjan(v,u);            lown[u] = min(lown[u],lown[v]);            if(lown[v] > dfn[u]) {                isBridge[i] = isBridge[i^1] = true;                cnt[i] = cnt[i^1] = dfs_clock-dfn[v];            }        }else {            lown[u] = min(lown[u],dfn[v]);        }    }}bool dfs(int u,LL s,LL x) {    vis[u] = true;    LL ts = cost[u];    int sz = sta.size();    for(int i = head[u]; i; i = e[i].nxt) {        int v = e[i].v, w = e[i].w;        if(isBridge[i] && !vis[v]) {            LL tmp = (LL)w*cnt[i]*(sz-cnt[i]);            if(!dfs(v,tmp,x)) return false;            if(!CanE[v]) ts += tmp;        }    }    if(ts > x) return false;    if(ts+s <= x)  CanE[u] = true;    return true;}bool can(LL x) {    int len = sta.size();    memset(CanE,false,sizeof CanE);    for(int i = 0; i < len; i++) vis[sta[i]] = false;    for(int i = 0; i < len; i++) {        int t = sta[i];        if(vis[t]) continue;        if(!dfs(t,0,x)) return false;    }    return true;}void init() {    nume = 1;    ans = 0;    dfs_clock = 1;    memset(head,0,sizeof head);    memset(isBridge,false,sizeof isBridge);    memset(vis,false,sizeof vis);    memset(dfn,0,sizeof dfn);    memset(lown,0,sizeof lown);    memset(CanE,false,sizeof CanE);    sta.clear();}void addedge(int u,int v,int w) {    e[++nume].nxt = head[u];    e[nume].u = u;    e[nume].v = v;    e[nume].w = w;    head[u] = nume;}void solve() {    for(int i = 1; i <= n; i++) {        if(!dfn[i]) {            sta.clear();            Tarjan(i,-1);            LL L = ans,R = 1e10;            while(L <= R) {                LL mid = (L+R)/2;                if(can(mid)) {                    R = mid-1;                }else{                    L = mid+1;                }            }            ans = max(ans,L);        }    }    printf("%lld\n",ans);}int main(){    int ncase,T=1;    cin >> ncase;    while(ncase--) {        init();        scanf("%d%d",&n,&m);        for(int i = 1; i <= n; i++) {            scanf("%lld",&cost[i]);            ans = max(ans,cost[i]);        }        for(int i = 0; i < m; i++) {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            addedge(a,b,c);            addedge(b,a,c);        }        printf("Case %d: ",T++);        solve();    }    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.