题意及解题思路:http://www.cnblogs.com/Fatedayt/archive/2012/05/10/2493967.html
#include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<queue> using namespace std; typedef long long ll; const int N=1010; const int M=40010; const ll inf=0x3f3f3f3f3f3fll; int n,m,id[N],val[N],q[2000000]; int head[N],ev[M],nxt[M],e; pair<int,int>ini[N]; bool vis[N]; ll ew[M],d[N][N]; void add(int u,int v,int w) { ev[e]=v;ew[e]=w;nxt[e]=head[u];head[u]=e++; } void spfa(int s) { int front=1000000,back=999999; memset(vis,0,s+1);vis[s]=1; d[s][s]=0;q[++back]=s; ll sum=d[s][s]; int u,v,i; while(back>=front) { vis[u=q[front++]]=0; sum-=d[s][u]; for(i=head[u];~i;i=nxt[i]) { v=ev[i]; if(v<=s&&d[s][u]+ew[i]<d[s][v]) { d[s][v]=d[s][u]+ew[i]; if(!vis[v]) { vis[v]=1;sum+=d[s][v]; if(d[s][q[front]]<d[s][v]) q[++back]=v; else q[--front]=v; } } } int sz=back+1-front; while(sz&&d[s][q[front]]*sz>sum) q[++back]=q[front++]; } } int main() { while(scanf("%d%d",&n,&m),n||m) { memset(head,-1,4*n+4);e=0; for(int i=1;i<=n;i++) for(int j=1;j<=i;j++) d[i][j]=inf; for(int i=1;i<=n;i++) { scanf("%d",&ini[i].first); ini[i].second=i; } sort(ini+1,ini+1+n); for(int i=1;i<=n;i++) { id[ini[i].second]=i; val[i]=ini[i].first; } int u,v,w; for(int i=0;i<m;i++) { scanf("%d%d%d",&u,&v,&w); u=id[u];v=id[v]; add(u,v,w);add(v,u,w); } for(int i=1;i<=n;i++) spfa(i); int q; scanf("%d",&q); while(q--) { scanf("%d%d",&u,&v); u=id[u];v=id[v]; ll tmp,ans=inf; for(int i=max(u,v);i<=n;i++) { tmp=d[i][u]+d[i][v]+val[i]; if(tmp<ans) ans=tmp; } printf("%lld\n",ans==inf?-1:ans); } puts(""); } return 0; }