题目就是说在时间的限制下,找一条最短路,且最短路的最小边最大。
对边进行排序,筛选可以符合条件的,进行二分,dist存放时间即可。
有个数组开小了无限TLE。。。然后就是二分,多理解二分。
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<string.h>
#define eps 1e-5
#define inf 0x7fffffff
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
int n,m,T;
int cap[50010];
int dist[15010],vis[15010];
int limit;
struct node{int des,val,time;};
vector<node> adj[10010];
int spfa()
{
for(int i=0;i<=n;i++) dist[i]=inf,vis[i]=0;
dist[1]=0;
queue<int> que;
que.push(1);
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int i=0;i<adj[u].size();i++){
int tmp=dist[u]+adj[u][i].time;
int v=adj[u][i].val,d=adj[u][i].des;
if(dist[d]>tmp&&v>=limit){
dist[d]=tmp;
if(!vis[d])
{
que.push(d);
vis[d]=1;
}
}
}
}
if(dist[n]<=T) return 1;
else return 0;
}
int cmp(int a,int b){return a>b;}
int main()
{
int _;scanf("%d",&_);while(_--)
{
scanf("%d%d%d",&n,&m,&T);
for(int i=0;i<=n;i++) adj[i].clear();
int a,b,c,d;
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
node p;
p.des=b;p.val=c;p.time=d;
adj[a].push_back(p);
p.des=a;
adj[b].push_back(p);
cap[i]=c;
}
sort(cap,cap+m,cmp);
int low=0,high=m-1,mid;
while(low<=high)
{
mid=(low+high)>>1;
limit=cap[mid];
if(spfa()==0) low=mid+1;
else high=mid-1;
}
printf("%d\n",cap[low]);
}
return 0;
}
用前向星的话内存少一点。
#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<queue>
#include<vector>
#include<string.h>
#define eps 1e-5
#define inf 0x7fffffff
#pragma comment(linker,"/STACK:102400000,102400000")
using namespace std;
int n,m,T;
int cap[50010];
int dist[15010],vis[15010];
int limit;
int head[10005],size;
struct Edge{int v,next,cap,time;}E[50005*2];
void addEdge(int u,int v,int c,int d){
E[size].v=v;
E[size].cap=c;
E[size].time=d;
E[size].next = head[u];
head[u] = size++;
}
int spfa()
{
for(int i=0;i<=n;i++) dist[i]=inf,vis[i]=0;
dist[1]=0;
queue<int> que;
que.push(1);
while(!que.empty())
{
int u=que.front();
que.pop();
vis[u]=0;
for(int e=head[u]; e!=-1; e=E[e].next){
int tmp=dist[u]+E[e].time;
int v=E[e].cap,d=E[e].v;
if(dist[d]>tmp&&v>=limit){
dist[d]=tmp;
if(!vis[d])
{
que.push(d);
vis[d]=1;
}
}
}
}
if(dist[n]<=T) return 1;
else return 0;
}
int cmp(int a,int b){return a>b;}
int main()
{
int _;scanf("%d",&_);while(_--)
{
memset(head,-1,sizeof head);
size=0;
scanf("%d%d%d",&n,&m,&T);
int a,b,c,d;
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&a,&b,&c,&d);
addEdge(a,b,c,d);
addEdge(b,a,c,d);
cap[i]=c;
}
sort(cap,cap+m,cmp);
int low=0,high=m-1,mid;
while(low<high)
{
mid=(low+high)>>1;
limit=cap[mid];
if(spfa()==0) low=mid+1;
else high=mid;
}
printf("%d\n",cap[low]);
}
return 0;
}