#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
上传者