uva1416 - Warfare And Logistics 最短路树优化

来源:互联网 发布:单片机bin文件反编译 编辑:程序博客网 时间:2024/05/22 10:49

The army of United Nations launched a new wave of air strikes on terroristforces. The objective of the mission is to reduce enemy's logistical mobility. Each airstrike will destroy a path and therefore increase the shipping cost of the shortest pathbetween two enemy locations. The maximal damage is always desirable.

Let's assume that there are n enemy locations connected bym bidirectional paths,each with specific shipping cost. Enemy's total shipping cost is given asc = $ \sum^{{n}}_{{i=1}}$$ \sum^{{n}}_{{j=1}}$path(i,j). Here path(i, j) is the shortest path between locationsi and j. In casei and j are not connected,path(i, j) = L. Each air strike can only destroy one path. The total shipping cost after the strike is noted asc'. In order to maximizedthe damage to the enemy, UN's air force try to find the maximalc' - c.

Input 

The first line ofeach input case consists ofthree integers: n, m, and L.1 < n$ \le$100,1$ \le$m$ \le$1000,1$ \le$L$ \le$10$\scriptstyle \wedge$8. Each ofthe following m lines contains three integers:a,b, s, indicating length of the path between a andb.

Output 

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

Sample Input 

4  6  10001  3  21  4  42  1  32  3  33  4  14  2  2

Sample Output 

28  38

  N个节点M条边的无向图,每条边上有个正权,c为每对节点的最短路长度之和。要求删除一条边后使得新的c值c'最大。不连通的两点最短路长度视为L。输出c'。

  如果用floyd,每删一条边计算一次,复杂度O(n^3m)。如果用N次dijkstra计算单源最短路,时间复杂度为O(nm^2logn)。

  在源点确定的情况下,只要最短路树不被破坏,起点到所有点的距离都不会改变,也就是只有删除最短路树上的N-1条边中的某条,最短路树才需要重新计算。因此每个源点,最多只要求N次而不是M次单源最短路,时间复杂度变为O(n^2mlohn)。

  注意有坑,可能有重边,这时要用第二短边代替。

  以前写最短路都没有写成结构体这样,并且加边也不像这个结构体里写的这样。这题修改边的时候就发现这样结构化的模版的好处了,有很多功能而且方便调用。

#include<iostream>#include<queue>#include<cstring>#include<cstdio>#include<cmath>#include<set>#include<map>#include<vector>#include<stack>#include<algorithm>#define INF 0x3f3f3f3f#define eps 1e-9#define MAXN 110#define MAXM 2000010#define MAXNODE 105#define MOD 100000#define SIGMA_SIZE 4typedef long long LL;using namespace std;int N,M,L,sum_single[MAXN],used[MAXN][MAXN][MAXN],idx[MAXN][MAXN];vector<int> g[MAXN][MAXN];struct Edge{    int u,v,dist;};struct HeapNode{    int u,d;    bool operator < (const HeapNode& rhs) const{        return d>rhs.d;    }};struct Dijkstra{    int n,m;    vector<Edge> edges;    vector<int> G[MAXN];    bool done[MAXN];    int d[MAXN];    int p[MAXN];    void init(int n){        this->n=n;        for(int i=0;i<n;i++) G[i].clear();        edges.clear();    }    void add_edge(int u,int v,int dist){        edges.push_back((Edge){u,v,dist});        m=edges.size();        G[u].push_back(m-1);    }    void dijkstra(int s){        priority_queue<HeapNode> q;        for(int i=0;i<n;i++) d[i]=INF;        d[s]=0;        q.push((HeapNode){s,0});        memset(done,0,sizeof(done));        while(!q.empty()){            HeapNode x=q.top();            q.pop();            int u=x.u;            if(done[u]) continue;            done[u]=true;            int L=G[u].size();            for(int i=0;i<L;i++){                Edge& e=edges[G[u][i]];                if(e.dist>0&&d[e.v]>d[u]+e.dist){                    d[e.v]=d[u]+e.dist;                    p[e.v]=G[u][i];                    q.push((HeapNode){e.v,d[e.v]});                }            }        }    }}solver;int cal(){    int ret=0;    memset(used,0,sizeof(used));    for(int src=0;src<N;src++){        solver.dijkstra(src);        sum_single[src]=0;        for(int i=0;i<N;i++){            if(i!=src){                int fa=solver.edges[solver.p[i]].u;                used[src][fa][i]=used[src][i][fa]=1;    //fa->i是以src为源最短路树上的边            }            sum_single[src]+=(solver.d[i]==INF?L:solver.d[i]);        }        ret+=sum_single[src];    }    return ret;}int cal_new(int a,int b){    int ret=0;    for(int src=0;src<N;src++){        if(!used[src][a][b]) ret+=sum_single[src];  //如果不在最短路树上src到各个点的最短路不变        else{            solver.dijkstra(src);            for(int i=0;i<N;i++) ret+=(solver.d[i]==INF?L:solver.d[i]);        }    }    return ret;}int main(){    freopen("in.txt","r",stdin);    while(scanf("%d%d%d",&N,&M,&L)!=EOF){        for(int i=0;i<N;i++)            for(int j=0;j<N;j++) g[i][j].clear();        solver.init(N);        int u,v,dist;        while(M--){            scanf("%d%d%d",&u,&v,&dist);            u--;            v--;            g[u][v].push_back(dist);            g[v][u].push_back(dist);        }        for(int u=0;u<N;u++)            for(int v=u+1;v<N;v++) if(!g[u][v].empty()){                sort(g[u][v].begin(),g[u][v].end());                solver.add_edge(u,v,g[u][v][0]);                idx[u][v]=solver.m-1;                solver.add_edge(v,u,g[u][v][0]);                idx[v][u]=solver.m-1;            }        int ans1=cal(),ans2=-1;        for(int i=0;i<N;i++)            for(int j=i+1;j<N;j++) if(!g[i][j].empty()){                int& e1=solver.edges[idx[i][j]].dist;                int& e2=solver.edges[idx[j][i]].dist;                if(g[i][j].size()==1) e1=e2=-1;                else e1=e2=g[i][j][1];                ans2=max(ans2,cal_new(i,j));                e1=e2=g[i][j][0];            }        printf("%d %d\n",ans1,ans2);    }    return 0;}



0 0
原创粉丝点击