- Telephone Lines
代码
- 2022-5-24 15:35:26 @
#include<cstdio>
#include<iostream>
#include<memory>
#include<queue>
#include<bits/stdc++.h>
using namespace std;
int head[100020],ver[1000020],edge[1000020],nxt[1000020],d[100020];
bool v[100020];
int n,m,k,tot,mid;
priority_queue< pair<int,int> > q; //优先队列
void add(int x,int y,int z){ //加边
ver[++tot]=y;
edge[tot]=z;
nxt[tot]=head[x];
head[x]=tot;
}
void dijkstra(){ //dijkstra模板
memset(d,0x3f,sizeof(d)); //因为是取min所以d[n]要开大点
memset(v,0,sizeof(v)); //初始化每个节点都没被访问过
d[1]=0; //初始化
q.push(make_pair(0,1));
while(q.size()){
int x=q.top().second;
q.pop();
if(v[x])continue;
v[x]=1; //加上访问标记
for(int i=head[x];i;i=nxt[i]){ //遍历以当前节点为起点的每一条边
int y=ver[i],z=edge[i];
if(z>mid)z=1; //把边权大于mid的边边权变为1
else z=0; //不超过mid的边权为0
if(d[y]>d[x]+z){ //三角形不等式
d[y]=d[x]+z; //更新最短路
q.push(make_pair(-d[y],y)); //堆优化
}
}
}
}
int main(){
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=m;i++){
int x,y,z; //起点终点边权
scanf("%d %d %d",&x,&y,&z);
add(x,y,z); //因为是双向边所以需要加两次
add(y,x,z);
}
int l=0,r=1000000;
int ans=-1;
while(l<=r){ //二分答案d[n]
mid=l+(r-l)/2;
dijkstra();
if(d[n]<=k){ //d[n]即1到n的最短路
r=mid-1;
ans=mid; //更新为最新的,因为二分越往后越接近目标(在这里是第K+1条边最小边权)
}
else l=mid+1;
}
printf("%d\n",ans); //好耶
return 0;
}
0 条评论
目前还没有评论...
信息
- ID
- 3
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 1
- 已通过
- 0
- 上传者