思路:题目求的是从S->T的路径中权值小于给定P值的最大值;这样的话我们就只能枚举假定必经过的边(枚举)<a,b>,
此时就是ans = dis<S->a> + w<a,b> + dis<b->T> 设纪录最终结果的变量是rec,如果rec < ans && ans <= P,那么rec = ans;
这里dis<S->a>显然由正向的单源最短路,那么dis<b->T>就是反向的单源最短路;
题目链接
/*限制性的最短路变种,求最短路中的最长边*/ /*两次spfa + dp*/ #include <iostream> #include <algorithm> #include <string> #include <stack> #include <queue> #include <vector> #include <map> #include <set> #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <limits.h> using namespace std; const int maxn = 22222; const int maxe = 222222; const int inf = 1 << 30; #define FILL(a,b) memset(a,b,sizeof a) #define CLR(a) memset(a,0,sizeof a) template<class T> inline T Get_Max(const T&a,const T&b) {return a < b?b:a;} template<class T> inline T Get_Min(const T&a,const T&b) {return a < b?a:b;} struct Edge { int v,w,next; }; Edge E1[maxe],E2[maxe]; int head1[maxn],head2[maxn]; int cnt1,cnt2,n,m,st,ed,p; inline void Addedge1(int u,int v,int w) { E1[cnt1].v = v; E1[cnt1].w = w; E1[cnt1].next = head1[u]; head1[u] = cnt1++; } inline void Addedge2(int u,int v,int w) { E2[cnt2].v = v; E2[cnt2].w = w; E2[cnt2].next = head2[u]; head2[u] = cnt2++; } int dis[2][maxn]; bool vis[maxn]; inline void spfa(int st,int ed,Edge *edge,int* dis,int *head) { FILL(vis,false); fill(dis,dis + 2 + n,inf); // memset(dis,inf,sizeof dis); queue<int> que; que.push(st); dis[st] = 0; vis[st] = true; while(!que.empty()) { int u = que.front(); que.pop(); vis[u] = false; for (int i = head[u];i != -1;i = edge[i].next) { int v = edge[i].v; int w = edge[i].w; if (dis[u] + w < dis[v]) { dis[v] = dis[u] + w; if (!vis[v]) { vis[v] = true; que.push(v); } } } } // cout << "dis = " << dis[n] << endl; // printf("n->1 %d\n",dis[1]); // printf("1->n %d\n",dis[n]); } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); int kase; int iCase = 0; int u,v,w; scanf("%d",&kase); while(kase--) { scanf("%d%d%d%d%d",&n,&m,&st,&ed,&p); cnt1 = cnt2 = 0; FILL(head1,-1); FILL(head2,-1); while(m--) { scanf("%d%d%d",&u,&v,&w); Addedge1(u,v,w); Addedge2(v,u,w); } spfa(st,ed,E1,dis[0],head1); spfa(ed,st,E2,dis[1],head2); int ans = -1; for (int u = 1;u <= n;u++) { for (int i = head1[u];i != -1;i = E1[i].next) { int v = E1[i].v; int w = E1[i].w; if (dis[0][u] < inf && dis[1][v] < inf && dis[0][u] + dis[1][v] + w <= p) { ans = Get_Max(ans,w); } } } printf("Case %d: %d\n",++iCase,ans); } return 0; }