标签:from with describes algorithm ice span decided esc max
时间限制: 1 Sec 内存限制: 64 MB
提交: 9 解决: 5
[提交][状态][讨论版]
5 7
2 1 5
1 3 1
3 2 8
3 5 7
3 4 3
2 4 7
4 5 2
2
There are 5 fields and 7 pathways. Currently, the shortest path from the house (field 1) to the barn (field 5) is 1-3-4-5 of total length 1+3+2=6.If the cows double the length of the pathway from field 3 to field 4 (increasing its length from 3 to 6), then FJ‘s shortest route is now 1-3-5, of total length 1+7=8, larger by two than the previous shortest route length.
【分析】农夫要从1走到n,他只走最短路。现在他的牛想使坏,想在一些路上设置障碍,使得这条路的长度变为2倍,求最短路的最大增量(农夫选择的)。先跑一边最段路,找前驱,然后将前驱所练成的每一条边依次遍历将其扩大二倍,再在只把该边扩大二倍的原图上跑最短路,找d[n]的最大值。可能存在很多的最短路,但是只用处理一条,因为即使有两条不相交的最短路,那么跑完之后d[n]还跟第一次跑的一样,不影响。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> #include <cmath> #include <string> #include <map> #include <stack> #include <queue> #include <vector> #define inf 0x3f3f3f3f #define met(a,b) memset(a,b,sizeof a) #define pb push_back typedef long long ll; using namespace std; const int N = 1e3; const int M = 24005; int n,m,k; int edgg[N][N]; int edg[N][N],vis[N],d[N],pre[N]; void spfa(int x) { met(vis,0); met(d,inf); d[1]=0; vis[1]=1; queue<int>q; q.push(1); while(!q.empty()){ int t=q.front();q.pop(); vis[t]=0; for(int i=0;i<=n+1;i++){ if(d[i]>d[t]+edg[t][i]){ d[i]=d[t]+edg[t][i]; if(!x)pre[i]=t; if(!vis[i])q.push(i),vis[i]=1; } } } } int main() { met(edg,inf); met(pre,-1); int ans1,ans2=0; scanf("%d%d",&n,&m); int u,v,w; while(m--){ scanf("%d%d%d",&u,&v,&w); edg[u][v]=edg[v][u]=w; } spfa(0); ans1=d[n]; for(int i=n;pre[i]!=-1;i--){ int v=pre[i]; edg[i][v]*=2; edg[v][i]*=2; spfa(1); ans2=max(ans2,d[n]); edg[i][v]/=2; edg[v][i]/=2; } printf("%d\n",ans2-ans1); return 0; }
标签:from with describes algorithm ice span decided esc max
原文地址:http://www.cnblogs.com/jianrenfang/p/6279717.html