Description
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 = 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 is noted as c' . In order to maximized the damage to the enemy, UN's air force try to find the maximal c' - c .
Input
The first line ofeach input case consists ofthree integers: n , m , and L . 1 < n100 , 1m1000 , 1L108 . Each ofthe followingm 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
思路:先进行n次最短路,算出原先的和sum_all;
然后对于删除每一条边所影响的最短路,进行重新最短路,算出新的sum_del,
900MS+
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; typedef long long LL; const LL oo=1e18; const int mm=100+9; const int nn=2000+9; class Edge { public:int v,next;LL dis; }e[nn]; class heap { public:int u;LL dis; bool operator <(const heap& x)const { return dis>x.dis; } }; int head[mm],edge,n,m,L; bool del[nn],vis[mm],belong[nn][mm];LL dis[mm][mm],dd[mm],sum_all,sum_del,sum_mid; void data() { memset(head,-1,sizeof(head));edge=0; } void add(int u,int v,LL _dis) { e[edge].v=v;e[edge].dis=_dis;e[edge].next=head[u];head[u]=edge++; } void dijstra(LL*d,int S,bool action) { memset(vis,0,sizeof(vis)); priority_queue<heap>Q; for(int i=0;i<=n;++i) d[i]=oo; d[S]=0; Q.push((heap){S,0}); heap z;int u,v; while(!Q.empty()) { z=Q.top();Q.pop(); u=z.u; if(vis[u])continue;vis[u]=1; for(int i=head[u];~i;i=e[i].next) { v=e[i].v; if(action&&del[i])continue;///i边已经删除 if(d[v]>d[u]+e[i].dis) { if(!action) {belong[i^1][S]=belong[i][S]=1;} d[v]=d[u]+e[i].dis;Q.push((heap){v,d[v]}); } } } if(!action) { for(int i=1;i<=n;++i) if(d[i]<oo)sum_all+=d[i]; else sum_all+=L; } else { for(int i=1;i<=n;++i) { if(dis[S][i]<oo)sum_mid-=dis[S][i]; else sum_mid-=L;///去除原边的影响 if(d[i]<oo)sum_mid+=d[i]; else sum_mid+=L;///加上新边 } } } int main() { int a,b,c; while(~scanf("%d%d%d",&n,&m,&L)) { data(); for(int i=0;i<m;++i) { scanf("%d%d%d",&a,&b,&c); add(a,b,c);add(b,a,c); } sum_all=0; memset(del,0,sizeof(del)); memset(belong,0,sizeof(belong)); for(int i=1;i<=n;++i) dijstra(dis[i],i,0); sum_del=sum_all; for(int i=0;i<m;++i) { sum_mid=sum_all; del[i+i]=del[i+i+1]=1; for(int j=1;j<=n;++j) if(belong[i+i][j])///这个优化很关键,有点难,源点固定的最短路会改变,当且仅当最短路上的边 dijstra(dd,j,1);///发生变动,而一条n点最短路最多n-1条边,因此最坏需要n*(n-1)次改变 if(sum_del<sum_mid)sum_del=sum_mid; del[i+i]=del[i+i+1]=0; } printf("%lld %lld\n",sum_all,sum_del); } return 0; }