LA4080 Warfare And Logistics (dijkstra+最短路树)

来源:互联网 发布:返利商城APP源码 编辑:程序博客网 时间:2024/05/19 18:37

题目链接:https://icpcarchive.ecs.baylor.edu/external/40/4080.pdf


题意:有n个顶点,m条边,path[i][j]表示从i到j的最短路径,如果从i到j不连通,则path[i][j] = L;现在求

然后删除一条边,求c1,使得c1 - c 的值最大。

思路:刚看到题目是让各点之间的最短路径和,所以立马想到啦floyd算法求最短路,然后发现还要去掉一条边后求最短路中的最大值,则floyd会超时,所以打算用dijkstra+堆优化做,首先枚举n个顶点求各个顶点之间的最短路径,并求出最短路树,然后枚举每条边,如果这条边在最短路树中,则再求一遍该点的最短路径即可,如果不在最短路树中,则直接利用第一次求得最短路即可。

所谓的最短路树是指在求最短路的同时,记录最短路径。


#include <cstdio>#include <queue>#include <cstring>#include <algorithm>#define LL long long#define inf 1LL << 50using namespace std;const int maxn = 110;const int maxp = 4e3 + 10;int head[maxp],n,m,L,cnt,vis[maxn],belong[maxp][maxn],p[maxn],delt[maxp];LL sum[maxn],dist[maxn];//belong[][]记录以s为原点的第i条边是否在s的最短路径中struct Edge{    int to,next,w,id;}edge[maxp];struct HeapNode{    int dist,v;    friend bool operator <(HeapNode A, HeapNode B){        return A.dist > B.dist;    }};void add(int u, int v, int w, int i){    edge[cnt].to = v;    edge[cnt].id = i;    edge[cnt].w = w;    edge[cnt].next = head[u];    head[u] = cnt ++;}void dijkstra(int x){    for(int i = 0; i <= n; i ++) dist[i] = inf, vis[i] = 0;    memset(p,0,sizeof(p));    dist[x] = 0;    priority_queue<HeapNode> q;    HeapNode no;    no.dist = 0; no.v = x;    q.push(no);    while(!q.empty()){        no = q.top(); q.pop();        if(vis[no.v]) continue;        belong[p[no.v]][x] = 1;        vis[no.v] = 1;        for(int i = head[no.v]; i != -1; i = edge[i].next){            int v = edge[i].to;            if(dist[v] > dist[no.v] + edge[i].w){                dist[v] = dist[no.v] + edge[i].w;                HeapNode hn;                p[v] = edge[i].id;                hn.dist = dist[v]; hn.v = v;                q.push(hn);            }        }    }    for(int i = 1; i <= n; i ++){        if(dist[i] == inf) sum[x] += L;        else sum[x] += dist[i];    }}int dij(int x){    for(int i = 0; i <= n; i ++) dist[i] = inf, vis[i] = 0;    dist[x] = 0;    priority_queue<HeapNode> q;    HeapNode no;    no.dist = 0; no.v = x;    q.push(no);    while(!q.empty()){        no = q.top(); q.pop();        if(vis[no.v]) continue;        vis[no.v] = 1;        for(int i = head[no.v]; i != -1; i = edge[i].next){            if(delt[edge[i].id]) continue;            int v = edge[i].to;            if(dist[v] > dist[no.v] + edge[i].w){                dist[v] = dist[no.v] + edge[i].w;                HeapNode hn;                hn.dist = dist[v]; hn.v = v;                q.push(hn);            }        }    }    int ans = 0;    for(int i = 1; i <= n; i ++){        if(dist[i] == inf) ans += L;        else ans += dist[i];    }    return ans;}int main(){    while(~scanf("%d%d%d",&n,&m,&L)){        cnt = 0;        int u,v,w;        memset(head,-1,sizeof(head));        for(int i = 1; i <= m; i ++){            scanf("%d%d%d",&u,&v,&w);            add(u,v,w,i);            add(v,u,w,i);        }        memset(belong,0,sizeof(belong));        for(int i = 1; i <= n; i ++){            sum[i] = 0;            dijkstra(i);        }        LL ans = 0, Max = 0;        memset(delt,0,sizeof(delt));        for(int i = 1; i <= n; i ++) ans += sum[i];        for(int i = 1; i <= m; i ++){            delt[i] = 1;            LL tmp = 0;            for(int j = 1; j <= n; j ++){                if(belong[i][j]) tmp += dij(j);                else tmp += sum[j];            }            delt[i] = 0;            Max = max(Max,tmp);        }        printf("%lld %lld\n",ans,Max);    }    return 0;}



原创粉丝点击