leo12334 @ 2023-01-12 14:04:51
用二分和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;
}
by 晴空一鹤 @ 2023-01-12 14:15:42
@leo12334 考虑是个稠密图就很劣了(进队的点扩大几倍),再加上这题本就有点卡常
by olegekei @ 2023-01-12 14:20:49
@leo12334 你可以试着开一个 O2,对速度有极大的提升
by leo12334 @ 2023-01-12 15:08:50
谢谢两位大佬解答!