【UVA1416】(LA4080) Warfare And Logistics (单源最短路)
题目:
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个节点m条无向边的图,每条边权都为正。令c等于每对结点的最短路长度之和。要求删一条边后使得新的c值c‘最大。不连通两点的最短路长度视为L。(1<=n<=100,1<=m<=1000,1<=L<=10^8)
分析:
因为规模比较小,所以可以考虑删边。主要是删什么边的问题。
这里用到最短路树。在源点确定的情况下,只要最短路树不被破坏,起点到所有点的距离都不会改变。所以对于一个点,只有删掉最短路树上的边,我们才要重新做一次单源最短路。时间复杂度是O(n^2mlogn)。
代码如下:
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 #define Maxn 110 9 #define Maxm 1100 10 #define INF 100000000 11 12 struct node 13 { 14 int x,y,c,next; 15 int ans; 16 bool p; 17 }t[Maxm*2];int len; 18 19 int first[Maxn],dis[Maxn]; 20 bool inq[Maxn]; 21 bool hp[Maxn]; 22 queue<int > q; 23 int n,m,L; 24 25 void ins(int x,int y,int c) 26 { 27 t[++len].x=x;t[len].y=y;t[len].c=c;t[len].ans=0; 28 t[len].next=first[x];first[x]=len; 29 } 30 31 int mymax(int x,int y) {return x>y?x:y;} 32 33 void spfa(int s,int l) 34 { 35 if(!q.empty()) q.pop(); 36 memset(inq,0,sizeof(inq)); 37 memset(dis,63,sizeof(dis)); 38 memset(hp,0,sizeof(hp)); 39 q.push(s);dis[s]=0;hp[s]=1;inq[s]=1; 40 while(!q.empty()) 41 { 42 int x=q.front();inq[x]=0;q.pop(); 43 for(int i=first[x];i;i=t[i].next) 44 { 45 if(i==l) continue; 46 if(i==(l%2==0?l-1:l+1)) continue; 47 int y=t[i].y;hp[y]=1; 48 if(dis[y]>dis[x]+t[i].c) 49 { 50 dis[y]=dis[x]+t[i].c; 51 if(!inq[y]) 52 { 53 q.push(y); 54 inq[y]=1; 55 } 56 } 57 } 58 } 59 } 60 61 int ffind(int s) 62 { 63 int now=0; 64 for(int i=1;i<=n;i++) if(i!=s) 65 { 66 if(hp[i]) now+=dis[i]; 67 else now+=L; 68 } 69 return now; 70 } 71 72 int main() 73 { 74 while(scanf("%d%d%d",&n,&m,&L)!=EOF) 75 { 76 memset(first,0,sizeof(first)); 77 len=0; 78 for(int i=1;i<=m;i++) 79 { 80 int x,y,c; 81 scanf("%d%d%d",&x,&y,&c); 82 ins(x,y,c);ins(y,x,c); 83 } 84 int ft=0; 85 for(int i=1;i<=n;i++) 86 { 87 spfa(i,0);int now=ffind(i); 88 ft+=now; 89 for(int j=1;j<=len;j++) t[j].p=0; 90 for(int j=1;j<=len;j++) 91 { 92 if(dis[t[j].x]==dis[t[j].y]+t[j].c) t[j].p=t[j%2==0?j-1:j+1].p=1; 93 } 94 for(int j=1;j<=len;j++) 95 if(t[j].p) 96 { 97 spfa(i,j); 98 t[j].ans+=ffind(i); 99 } 100 else t[j].ans+=now; 101 } 102 int mx=ft; 103 for(int i=1;i<=len;i++) mx=mymax(mx,t[i].ans); 104 printf("%d %d\n",ft,mx); 105 } 106 return 0; 107 }
2016-04-05 14:04:01