K-th Path
题目大意
一个
n
n
n 个点
m
m
m 条边的无向连通图,给你
n
n
n 个点,
m
m
m 条边,输出无向图中单源最短路径第
k
k
k 小的值。
m
m
m 条边,给出点
x
x
x 和
y
y
y 以及权值
w
w
w,点
x
x
x 到
y
y
y 和点
y
y
y 到
x
x
x 只会计算一次。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=(int)1e6+100;
int n,m,k,q[maxn],cnt,tot,h[maxn],p,vis[maxn],v,num;
ll dis[maxn],ans[maxn];
queue<int>Q;
struct kk{
int x,y;ll w;
bool operator<(const kk &a)const{
return w<a.w;
}
}a[maxn];
struct node{
int to,next;
ll w;
}edge[maxn<<1];
void add(int x,int y,ll z)
{
edge[++tot].to=y;
edge[tot].next=h[x];
edge[tot].w=z;
h[x]=tot;
}
int main()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;++i) scanf("%d%d%lld",&a[i].x,&a[i].y,&a[i].w);
sort(a+1,a+m+1);
for(int i=1;i<=k;++i) q[++cnt]=a[i].x,q[++cnt]=a[i].y,add(a[i].x,a[i].y,a[i].w),add(a[i].y,a[i].x,a[i].w);
sort(q+1,q+cnt+1);
cnt=unique(q+1,q+cnt+1)-q-1;
for(int i=1;i<=cnt;++i){
int u=q[i];
for(int j=1;j<=cnt;++j) dis[q[j]]=(ll)1e18;
dis[u]=0; Q.push(u);
while (!Q.empty()){
p=Q.front(),Q.pop();vis[p]=0;
for (int k=h[p];k;k=edge[k].next)
if(dis[v=edge[k].to]>dis[p]+edge[k].w){
dis[v]=dis[p]+edge[k].w;
if (!vis[v]) Q.push(v),vis[v]=1;
}
}
for(int j=1;j<=cnt;++j) if(i<j) ans[++num]=dis[q[j]];
}
sort(ans+1,ans+num+1);
printf("%lld\n",ans[k]);
return 0;
}