关于二分+dij堆优化超时的疑惑
查看原帖
关于二分+dij堆优化超时的疑惑
716721
leo12334楼主2023/1/12 14:04

用二分和dij堆优化写的,一开始没有加

if(vis[y])continue;

然后就只有60分,有4个点TLE,加了以后就AC了。但我在前边取出队列元素x的时候会进行vis[x]判断,如果访问过就会跳过,后边再加上vis[y]的判断仅会省略两组if和一组入队出队操作,这对时间效率影响很大吗?

#include<bits/stdc++.h>
using namespace std;
#define N 123456
#define M 223456
#define pii pair<int,int>
#define mp(x,y) make_pair(x,y)
int n,m,b,x,y,z,l=1e9+1,r,mid;
int a[N],vis[N],dis[N],ans,cnt,head[N],cost[N],maxn;
struct edge{
	int to,next,w;
}e[M];
void add(int x,int y,int z){
	e[++cnt].to=y;
	e[cnt].next=head[x];
	e[cnt].w=z;
	head[x]=cnt;
}
int dijiesitela(int max_cost){
	priority_queue< pii >q;
	memset(vis,0,sizeof(vis));
	memset(dis,0x3f,sizeof(dis));
	dis[1]=0;
	q.push(mp(0,1));
	while(q.size()){
		int x=q.top().second;q.pop();
		if(vis[x])continue;
		vis[x]=1;
		for(int i=head[x];i;i=e[i].next){
			int y=e[i].to,v=e[i].w;
			if(vis[y])continue;
			if(cost[y]>max_cost) continue;//费用大于ans的城市要跳过
			if(dis[y]>dis[x]+v) dis[y]=dis[x]+v;
			q.push(mp(-dis[y],y));
		}
	}
	
	return dis[n];
}
int main(){
	cin>>n>>m>>b;
	for(int i=1;i<=n;i++){
		cin>>cost[i];
		r=max(r,cost[i]);
	}
	l=max(cost[1],cost[n]);
	while(m--){
		cin>>x>>y>>z;
		add(x,y,z);
		add(y,x,z);
	}
	if(dijiesitela(r)>b){puts("AFK");return 0;}//先测试最短路的可行性
	
	while(l<r){
		mid=(l+r)/2;
		if(dijiesitela(mid)>b)l=mid+1;
		else r=mid;
	}
	cout<<l<<endl;
}
2023/1/12 14:04
加载中...