将所有路径上的capacity保存下来,并进行二分查找,每次枚举一个capacity值,选路径是去掉capacity小于枚举值的边,判断是否存在小于等于时间t的最短路径
若存在,则枚举值满足条件,继续寻找比枚举值大的,否则,寻找比枚举值小的
只能用spfa,迪杰斯特拉超时
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <queue>
using namespace std;
#define i64 long long
int n,m,t;
int cap[50005];
struct Edge
{
int to;
int w;
i64 c;
int next;
}edge[100005];
int head[10005];
bool visit[10005];
int dis[10005];
i64 ans ;
const int inf = 0x7fffffff;
bool dijkstra(i64 len)
{
for(int i = 1;i<=n;i++)
{
visit[i] = false;
dis[i] = inf;
}
dis[1] = 0;
visit[1] = true;
queue <int> q;
q.push(1);
while(!q.empty())
{
int temp = q.front();
q.pop();
for(int i = head[temp];i!=0;i=edge[i].next)
{
int to = edge[i].to;
int w = edge[i].w;
int c = edge[i].c;
if(c>=len&&dis[to]>dis[temp]+w)
{
dis[to] = dis[temp]+w;
if(!visit[to]) {q.push(to);visit[to] = true;}
}
}
visit[temp] = false;
}
if(dis[n]<=t)
return true;
return false;
}
void solve(int s,int e)
{
while(s<=e)
{
int mid = (s+e)/2;
if(dijkstra(cap[mid])) {
s = mid+1;
ans = cap[mid];
}
else e = mid-1;
}
}
void init()
{
for(int i = 0;i<=n;i++)
{
head[i] = 0;
}
}
int main()
{
int x,u,v,w;
i64 c;
scanf("%d",&x);
while(x--)
{
scanf("%d %d %d",&n,&m,&t);
init();
ans = 0;
for(int i = 1;i<=2*m;i++)
{
scanf("%d %d %I64d %d",&u,&v,&c,&w);
edge[i].to = v;
edge[i].c = c;
edge[i].w = w;
edge[i].next = head[u];
head[u] = i;
i++;
edge[i].to = u;
edge[i].c = c;
edge[i].w = w;
edge[i].next = head[v];
head[v] = i;
cap[i/2] =c;
}
sort(cap,cap+m+1);
solve(1,m);
printf("%I64d\n",ans);
}
return 0;
}