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 speci?c shipping cost. Enemy’s total shipping cost is given as
c =n ∑ i=1n ∑ j=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 is noted as c′. In order to maximized the damage to the enemy, UN’s air force try to ?nd the maximal c′?c.
Input The ?rst 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
题目大意:
有一个n(1<n<=100)节点,m(1<m<=1000)条边的无向图,每条边上有一个正权
令 c 等于每队节点之间的最短路之和(如果节点不连通最短路的值为L)
现要删除一条边,使得新的 c 值最大。
--------------------------------------------------------华丽的分割线----------------------------------------------------------------------------
解析:
我们可以先用dijkstra求出最短路树
找到n个节点之间最短路所用的n-1条边
再来考虑删除边
如果不是那n-1条边的其中之一
那么删除后 c 值不会发生该变
所以我们只用考虑删除那n-1条边其中一条的情况
时间复杂度为(n2m logn)
可以接受
代码如下:
1 #include<queue> 2 #include<stdio.h> 3 #include<string.h> 4 #include<algorithm> 5 using namespace std; 6 #define N 3005 7 #define LL long long 8 int n,m,l; 9 struct edge 10 { 11 int w,v,next; 12 }e[N<<2]; 13 int head[N]; 14 int tot; 15 int done[N]; 16 int vis[N<<2]; 17 LL sum[N][N<<2]; 18 LL dis[N]; 19 void add(int x,int y,int v) 20 { 21 e[tot].v=y; 22 e[tot].w=v; 23 e[tot].next=head[x]; 24 head[x]=tot++; 25 } 26 struct mypoint 27 { 28 int id,w,pre; 29 bool operator <(const mypoint &a)const 30 { 31 return w>a.w; 32 } 33 }s,ss; 34 LL dijkstra(int s,int f1,int f2) 35 { 36 priority_queue<mypoint>Q; 37 memset(done,0,sizeof(done)); 38 for(int i=1;i<=n;i++)dis[i]=l; 39 mypoint p; 40 p.w=0,p.id=s,p.pre=-1; 41 dis[s]=0; 42 Q.push(p); 43 while(!Q.empty()) 44 { 45 p=Q.top();Q.pop(); 46 if(done[p.id])continue; 47 done[p.id]=1; 48 if(f1==tot&&f2==tot&&p.id!=s) 49 vis[p.pre]=vis[p.pre^1]=1; 50 for(int k=head[p.id];k!=-1;k=e[k].next) 51 { 52 if(k==f1||k==f2)continue; 53 int u=p.id,v=e[k].v,len=e[k].w; 54 if(dis[v]>dis[u]+len) 55 { 56 dis[v]=dis[u]+len; 57 mypoint q; 58 q.id=v,q.w=dis[v],q.pre=k; 59 Q.push(q); 60 } 61 } 62 } 63 LL sum=0; 64 for(int i=1;i<=n;i++)sum+=dis[i]; 65 return sum; 66 } 67 int main() 68 { 69 while(~scanf("%d%d%d",&n,&m,&l)) 70 { 71 memset(head,-1,sizeof(head)); 72 tot=0; 73 for(int i=0;i<m;i++) 74 { 75 int x,y,v; 76 scanf("%d%d%d",&x,&y,&v); 77 add(x,y,v); 78 add(y,x,v); 79 } 80 /* for(int i=head[1];i;i=e[i].next) 81 { 82 printf("%d",e[i].v); 83 }*/ 84 // printf("%d",tot); 85 for(int i=1;i<=n;i++) 86 { 87 memset(vis,0,sizeof(vis)); 88 sum[i][tot]=dijkstra(i,tot,tot); 89 for(int j=0;j<tot;j++) 90 { 91 if(vis[j]==0)sum[i][j]=sum[i][tot]; 92 else sum[i][j]=dijkstra(i,j,j^1); 93 } 94 } 95 LL ans1=0,ans2=0; 96 for(int j=0;j<tot;j++) 97 { 98 LL cur=0; 99 for(int i=1;i<=n;i++) 100 { 101 cur+=sum[i][j]; 102 } 103 ans2=max(ans2,cur); 104 } 105 for(int i=1;i<=n;i++) 106 { 107 ans1+=sum[i][tot]; 108 } 109 printf("%lld %lld\n",ans1,ans2); 110 } 111 return 0; 112 }