给定一个无向图,求两点之间的最短距离。这里的两点距离是指两点之间的路径权之和加上包括两点在内的所有经过的点中,点权最大点的点权。
解法是floyd,但是需要变化一下。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct T { int n; int v; }; T p[260]; int g[260][260],f[260][260],pv[260]; int n; bool cmp(T a,T b) { return a.v<b.v; } int maxd(int c,...) { int *t,i,m; t=&c+1; m=(*t); t++; for (i=1; i<c; i++) { m=m>(*t)?m:(*t); t++; } return m; } int mind(int c,...) { int *t,i,m; t=&c+1; m=(*t); t++; for (i=1; i<c; i++) { m=m<(*t)?m:(*t); t++; } return m; } void floyd() { int i,j,k; for (k=1; k<=n; k++) { for (i=1; i<=n; i++) { for (j=1; j<=n; j++) { if (g[p[i].n][p[j].n] >= g[p[i].n][p[k].n]+g[p[k].n][p[j].n]) { g[p[i].n][p[j].n]=g[p[i].n][p[k].n]+g[p[k].n][p[j].n]; f[p[i].n][p[j].n]=mind(2,f[p[i].n][p[j].n],g[p[i].n][p[j].n]+maxd(3,pv[p[i].n],pv[p[j].n],pv[p[k].n])); } } } } } int main() { int m,k,i,j,t1,t2,t3; scanf("%d%d%d",&n,&m,&k); memset(g,0x3f,sizeof(g)); memset(f,0x3f,sizeof(f)); for (i=1; i<=n; i++) { g[i][i]=0; p[i].n=i; scanf("%d",&p[i].v); pv[i]=p[i].v; } sort(p+1,p+n+1,cmp); while (m--) { scanf("%d%d%d",&t1,&t2,&t3); g[t1][t2]=g[t1][t2]<t3?g[t1][t2]:t3; g[t2][t1]=g[t2][t1]<t3?g[t2][t1]:t3; } floyd(); while (k--) { scanf("%d%d",&t1,&t2); printf("%d\n",f[t1][t2]); } }