10-22 warfare and logistics(最短路树)

来源:互联网 发布:手机优化工具 编辑:程序博客网 时间:2024/06/05 06:03

Warfare And Logistics

The army of United Nations launched a new wave of air strikes on terrorist forces. The objective of
the mission is to reduce enemy’s logistical mobility. Each air strike will destroy a path and therefore
increase the shipping cost of the shortest path between two enemy locations. The maximal damage is
always desirable.
Let’s assume that there are n enemy locations connected by m bidirectional paths, each with specific shipping cost. Enemy’s total shipping cost is given as
c =∑ni=1∑nj=1 path(i, j)
Here path(i, j) is the shortest path between locations i and j. In case i and j are not connected,path(i, j) = L. Each air strike can only destroy one path. The total shipping cost after the strike isnoted as c′. In order to maximized the damage to the enemy, UN’s air force try to find the maximalc′ − c.

Input

The first line of each input case consists of three integers: n, m, and L. 1 < n ≤ 100, 1 ≤ m ≤ 1000,
1 ≤ L ≤ 108
. Each of the following m lines contains three integers: a, b, s, indicating length of the
path between a and b.

Output

For each case, output the total shipping cost before the air strike and the maximal total shipping cost
after the strike. Output them in one line separated by a space.

Sample Input

4 6 1000
1 3 2
1 4 4
2 1 3
2 3 3
3 4 1
4 2 2

Sample Output

28 38

最短路树-> 数据结构中的树与图论的结合
神奇

#include <bits/stdc++.h>using namespace std;const int maxn = 110;typedef pair<int, int> pii;vector<pii> vec[maxn];int d[maxn][maxn];int d2[maxn][maxn];int pre[maxn][maxn];long long rec[maxn];bool app[maxn];int n, m, l;const int INF = 0x3f3f3f3f;void add_edge(int a, int b, int s){    vec[a].push_back(make_pair(b, s));    vec[b].push_back(make_pair(a, s));}void spfa(int s, int d[maxn][maxn]){    for(int i = 1; i <= n; i++) d[s][i]=INF;    d[s][s] = 0;    queue<int> que;    memset(app, 0, sizeof(app));    que.push(s);    while(!que.empty()){        int u = que.front();        app[u] = false;que.pop();        for(int i = 0; i < vec[u].size(); i++){            int v = vec[u][i].first;            int dist = vec[u][i].second;            if(d[s][v]>d[s][u]+dist){                pre[s][v] = u;                d[s][v] = d[s][u]+dist;                if(!app[v]){                    app[v] = true;                    que.push(v);                }            }        }    }}void init(int n){    memset(pre, 0, sizeof(pre));    for(int i = 1; i <= n; i++)        spfa(i, d);}long long cal(int s, int d[maxn][maxn]){    long long ans = d[s][s];    for(int i = 1; i < s; i++){        if(d[s][i] == INF) d[s][i]=l;        ans += 2*(long long)d[s][i];    }    return ans;}vector<pair<pii, int> > edge;void find_del(int u, int v, int dist){    for(int i = 0; i < vec[u].size(); i++)        if(vec[u][i].first == v && vec[u][i].second == dist){            vec[u].erase(vec[u].begin()+i); return;        }}long long solve(int u, int v, int dist){    long long ans = 0;    for(int i = 1; i <= n; i++){        if(pre[i][u] != v && pre[i][v] != u){            ans += rec[i]; continue;        }        find_del(u, v, dist);        find_del(v, u, dist);        spfa(i, d2);        ans += cal(i, d2);        add_edge(u, v, dist);    }    return ans;}int main(){    while(~scanf("%d%d%d",&n, &m, &l)){        for(int i = 0; i <= n; i++) vec[i].clear();        edge.clear();        for(int i = 0; i < m; i++){            int a, b, s;            scanf("%d%d%d", &a, &b, &s);            edge.push_back(make_pair(make_pair(a, b), s));            add_edge(a, b, s);        }        init(n);        long long ans = 0;        for(int i = 1; i <= n; i++)            ans += rec[i]=cal(i, d);        printf("%lld ", ans);        for(int i = 0; i < edge.size(); i++){            long long ret = solve(edge[i].first.first, edge[i].first.second, edge[i].second);            ans = max(ans, ret);        }        printf("%lld\n", ans);    }    return 0;}
阅读全文
0 0
原创粉丝点击