1. 程式人生 > >UvaLive 4080 Warfare And Logistics

UvaLive 4080 Warfare And Logistics

int des poi string mic gis mil per tput

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 }

UvaLive 4080 Warfare And Logistics