P2966 [USACO09DEC]牛收费路径Cow Toll Paths
把点按点权排序,floyd处理最短路径与最小的 ( 路径与最大点权的和),k作为中间节点,能更新的时候,k是当前最大的点权
1 #include<algorithm> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdio> 5 #include<cmath> 6 #include<queue> 7 using namespace std; 8 #define maxn 10000*2+15 9 #define maxm 1000+15 10 int n,m,kk,c[maxn],o[maxn]; 11 int f[maxm][maxm],g[maxm][maxm]; 12 13 struct Edge{ 14 int id,num; 15 }e[maxn]; 16 bool cmp(Edge a,Edge b){ return a.num<b.num; } 17 int main() 18 { 19 scanf("%d%d%d",&n,&m,&kk); 20 for(int i=1;i<=n;i++) scanf("%d",&e[i].num),e[i].id=i; 21 sort(e+1,e+n+1,cmp); 22 memset(f,0x3f3f3f3f,sizeof(f)); 23 memset(g,0x3f3f3f3f,sizeof(g)); 24 for(int i=1;i<=n;i++) o[e[i].id]=i; 25 for(int i=1;i<=m;i++) 26 { 27 int a,b,c; 28 scanf("%d%d%d",&a,&b,&c); 29 a=o[a]; b=o[b]; 30 f[a][b]=f[b][a]=min(f[a][b],c); 31 } 32 for(int i=1;i<=n;i++) f[i][i]=0; 33 for(int k=1;k<=n;k++) 34 for(int j=1;j<=n;j++) 35 for(int i=1;i<=n;i++) 36 { 37 f[i][j]=min(f[i][j],f[i][k]+f[j][k]); 38 g[i][j]=min(g[i][j],f[i][j]+max(e[k].num,max(e[i].num,e[j].num))); 39 } 40 while(kk--) 41 { 42 int s,t; 43 scanf("%d%d",&s,&t); 44 if(f[o[s]][o[t]]>1e9) printf("-1 "); 45 else printf("%d ",g[o[s]][o[t]]); 46 } 47 return 0; 48 }