Deformation of the shortest path. Because the maximum vertex weight must be added, only the shortest path with each vertex as the starting point and the maximum vertex weight can be enumerated.
For each query, min = min (Min, DIS [I] [s] + dis [I] [T] + val [I]) is displayed.
Then this question needs to be optimized in many details.
For example, you can use global to use global.
Then I made another spfa .... I can't even write it ....
In the past, BFs + priority_queue was used to write the shortest short circuit, but it was slower than spfa...
------------------------- Updata ------------------------------
In fact, BFs + priority_queue is quite good... it must have been the last write failure .... The BFS + priority_queue code is appended to the end.
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <stack>#include <map>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long#define ULL unsigned long long#define _LL __int64#define INF 1e18#define Mod 6000007using namespace std;LL val[1010];struct N{ LL w; int v,next;}edge[40010];int head[1010];int Top;void Link(int u,int v,LL w){ edge[Top].v = v; edge[Top].w = w; edge[Top].next = head[u]; head[u] = Top++;}LL dis[1010];bool mark[1010];queue<int> q;void Cal(int s,int n){ memset(mark,false,sizeof(bool)*(n+2)); int f,t; for(int i = 1;i <= n; ++i) dis[i] = INF; f = s; dis[s] = 0; q.push(f); mark[s] = true; while(q.empty() == false) { f = q.front(); q.pop(); mark[f] = false; for(int p = head[f];p != -1; p = edge[p].next) { if(val[edge[p].v] > val[s]) continue; if(dis[f] + edge[p].w < dis[edge[p].v]) { dis[edge[p].v] = dis[f] + edge[p].w; if(mark[edge[p].v] == false) { mark[edge[p].v] = true; t = edge[p].v; q.push(t); } } } }}int S[20010],T[20010];LL Min[20010];int main(){ int n,m,i,j,u,v; LL w; while(scanf("%d %d",&n,&m) && (n||m)) { memset(head,-1,sizeof(int)*(n+2)); Top = 0; for(i = 1;i <= n; ++i) { scanf("%lld",&val[i]); } for(i = 1;i <= m; ++i) { scanf("%d %d %lld",&u,&v,&w); Link(u,v,w); Link(v,u,w); } scanf("%d",&m); for(i = 0;i < m; ++i) { scanf("%d %d",&S[i],&T[i]); Min[i] = INF; } for(i = 1;i <= n; ++i) { Cal(i,n); for(w = 0;w < m; ++w) { Min[w] = min(Min[w],dis[S[w]] + dis[T[w]] + val[i]); } } for(i = 0;i < m; ++i) { if(Min[i] == INF) printf("-1\n"); else printf("%lld\n",Min[i]); } printf("\n"); } return 0;}
BFS + priority_queue
#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <queue>#include <cmath>#include <stack>#include <map>#pragma comment(linker, "/STACK:1024000000");#define EPS (1e-8)#define LL long long#define ULL unsigned long long#define _LL __int64#define INF 1e18#define Mod 6000007using namespace std;LL val[1010];struct N{ LL w; int v,next;}edge[40010];int head[1010];int Top;void Link(int u,int v,LL w){ edge[Top].v = v; edge[Top].w = w; edge[Top].next = head[u]; head[u] = Top++;}LL dis[1010];bool mark[1010];struct Q{ int v; LL cost; bool operator < (const Q &a) const { return a.cost < cost; }};priority_queue<Q> q;void Cal(int s,int n){ memset(mark,false,sizeof(bool)*(n+2)); Q f,t; for(int i = 1;i <= n; ++i) dis[i] = INF; f.v = s; f.cost = 0; q.push(f); while(q.empty() == false) { f = q.top(); q.pop(); if(mark[f.v]) continue; mark[f.v] = true; dis[f.v] = f.cost; for(int p = head[f.v];p != -1; p = edge[p].next) { if(val[edge[p].v] > val[s]) continue; t.v = edge[p].v; t.cost = edge[p].w + f.cost; if(dis[t.v] > t.cost) { dis[t.v] = t.cost; q.push(t); } } }}int S[20010],T[20010];LL Min[20010];int main(){ int n,m,i,j,u,v; LL w; while(scanf("%d %d",&n,&m) && (n||m)) { memset(head,-1,sizeof(int)*(n+2)); Top = 0; for(i = 1;i <= n; ++i) { scanf("%lld",&val[i]); } for(i = 1;i <= m; ++i) { scanf("%d %d %lld",&u,&v,&w); Link(u,v,w); Link(v,u,w); } scanf("%d",&m); for(i = 0;i < m; ++i) { scanf("%d %d",&S[i],&T[i]); Min[i] = INF; } for(i = 1;i <= n; ++i) { Cal(i,n); for(w = 0;w < m; ++w) { Min[w] = min(Min[w],dis[S[w]] + dis[T[w]] + val[i]); } } for(i = 0;i < m; ++i) { if(Min[i] == INF) printf("-1\n"); else printf("%lld\n",Min[i]); } printf("\n"); } return 0;}