Floyd神用法。。。设dis[i][j]表示i点到j点的最短路(只算边权),map[i][j]表示i到j最小费用
将n个点先按照点权排一下序。。。这样就可以比较方便的求出路径上最大点权了。。。
因为floyd会枚举到路径上的所有节点(当然也包括最短路径外的= =)所以每次找到松弛节点就尝试着更新一下map(最短路不一定费用最少)。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=253; 7 struct point{ 8 int pos,val; 9 }poi[maxn]; 10 int ans[10023],dis[maxn][maxn],map[maxn][maxn]; 11 int i,j,k,n,m,K,tot,a,b,d,num; 12 int ra;char rx; 13 inline int read(){ 14 rx=getchar();ra=0; 15 while(rx<'0'||rx>'9')rx=getchar(); 16 while(rx>='0'&&rx<='9')ra*=10,ra+=rx-48,rx=getchar();return ra; 17 } 18 bool cmp(point a,point b){return a.val<b.val;} 19 int main(){ 20 n=read();m=read();K=read(); 21 for(i=1;i<=n;i++)poi[i].val=read(),poi[i].pos=i; 22 sort(poi+1,poi+1+n,cmp); 23 for(i=1;i<=n;i++)memset(dis[i],50,(n+1)<<2),memset(map[i],50,(n+1)<<2),dis[i][i]=0; 24 for(i=1;i<=m;i++)a=read(),b=read(),d=read(),dis[b][a]=dis[a][b]=min(dis[a][b],d); 25 for(k=1,d=poi[k].pos;k<=n;k++,d=poi[k].pos) 26 for(i=1,a=poi[i].pos;i<=n;i++,a=poi[i].pos)for(j=1,b=poi[j].pos;j<=n;j++,b=poi[j].pos){ 27 if(dis[a][d]+dis[d][b]<dis[a][b])dis[a][b]=dis[a][d]+dis[d][b]; 28 map[a][b]=min(map[a][b],dis[a][b]+poi[max(i,max(j,k))].val); 29 } 30 for(i=1;i<=K;i++)a=read(),b=read(),printf("%d ",map[a][b]); 31 return 0; 32 }