Consider an undirected graph with N vertices, numbered from 1 to N, and M edges. The vertex numbered with 1 corresponds to a mine from where some precious minerals are extracted. The vertex numbered with N corresponds to a minerals processing factory. Each edge has an associated travel time (in time units) and capacity (in units of minerals). It has been decided that the minerals which are extracted from the mine will be delivered to the factory using a single path. This path should have the highest capacity possible, in order to be able to transport simultaneously as many units of minerals as possible. The capacity of a path is equal to the smallest capacity of any of its edges. However, the minerals are very sensitive and, once extracted from the mine, they will start decomposing after T time units, unless they reach the factory within this time interval. Therefore, the total travel time of the chosen path (the sum of the travel times of its edges) should be less or equal to T.
2 2 1 10 1 2 13 10 4 4 20 1 2 1000 15 2 4 999 6 1 3 100 15 3 4 99 4
13 99
这道题还是一道二分的题,毕竟直接枚举也不太现实
#include <iostream>
#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 1e16
using namespace std;
/*
第一次双向队列过题,爽啊
*/
typedef long long ll;
int cnt;
int n,m,limit;
int head[100010];
ll dis[50010];
int vis[50010];
struct node
{
int t,c;
}w[50010];
struct edge
{
int v,next;
int time,capa;
}Edge[100010];
void add_edge(int u,int v,int c,int t)
{
Edge[cnt].v=v;
Edge[cnt].time=t,Edge[cnt].capa=c;
Edge[cnt].next=head[u];
head[u]=cnt++;
}
int cmp(node a,node b)
{
if(a.c<b.c)
return 1;
else
return 0;
}
ll spfa(int road_limit)
{
for(int i=0;i<=n;i++)
dis[i]=INF;
memset(vis,0,sizeof(vis));
dis[1]=0;
vis[1]=1;
deque<int> q;
q.push_back(1);
while(q.size())
{
int now=q.front();
q.pop_front();
vis[now]=0;
for(int i=head[now];i!=-1;i=Edge[i].next)
{
int v=Edge[i].v,t=Edge[i].time,c=Edge[i].capa;
if(c>=road_limit&&dis[v]>dis[now]+t)//满足道路承载能力,我们才回去松弛这条道路
{
dis[v]=dis[now]+t;
if(!vis[v])
{
vis[v]=1;
if(q.size())
{
if(dis[v]>dis[q.front()])
q.push_back(v);
else
q.push_front(v);
}
else
q.push_back(v);
}
}
}
}
return dis[n];
}
int main()
{
int T;
scanf("%d",&T);//以后这种多少个case,你就写大写的T吧,不要再重名了,这种错误真的很难找
while(T--)
{
cnt=0;
memset(head,-1,sizeof(head));
memset(Edge,0,sizeof(Edge));
memset(w,0,sizeof(w));
scanf("%d %d %d",&n,&m,&limit);
for(int i=0;i<m;i++)
{
int u,v,t,c;
scanf("%d %d %d %d",&u,&v,&c,&t);
add_edge(u,v,c,t);
add_edge(v,u,c,t);
w[i].c=c,w[i].t=t;;
}
sort(w,w+m,cmp);
int l=0,r=m-1,mid;
while(l<=r)
{
mid=(l+r)/2;
ll temp=spfa(w[mid].c);//高度值
if(temp!=INF&&temp<=limit)
{
l=mid+1;
}
else
r=mid-1;
}
printf("%d\n",w[r].c);
}
return 0;
}