F. K-th Path
You are given a connected undirected weighted graph consisting of nnn vertices and mmm edges.
You need to print the k−thk-thk−th smallest shortest path in this graph (paths from the vertex to itself are not counted, paths from iii to jjj and from jjj to iii are counted as one).
More formally, if ddd is the matrix of shortest paths, where di,jd_{i,j}di,j is the length of the shortest path between vertices iii and jjj (1≤i<j≤n)(1\leq i<j \leq n)(1≤i<j≤n), then you need to print the k−thk-thk−th element in the sorted array consisting of all di,jd_{i,j}di,j, where 1≤i<j≤n1\leq i<j\leq n1≤i<j≤n.
Input
The first line of the input contains three integers n,mn,mn,m and kkk (2≤n≤2⋅105,n−1≤m≤min(n×(n−1)2,2×105),1≤k≤min(n×(n−1)2,400)(2\leq n\leq 2⋅10^5, n−1\leq m\leq min(\frac{n\times (n−1)}{2},2 \times10^5), 1\leq k\leq min(\frac{n\times (n−1)}{2},400)(2≤n≤2⋅105,n−1≤m≤min(2n×(n−1),2×105),1≤k≤min(2n×(n−1),400) — the number of vertices in the graph, the number of edges in the graph and the value of kkk, correspondingly.
Then mmm lines follow, each containing three integers x,yx, yx,y and www (1≤x,y≤n,1≤w≤109,x!=y)(1\leq x,y \leq n, 1\leq w \leq 10^9, x !=y)(1≤x,y≤n,1≤w≤109,x!=y) denoting an edge between vertices xxx and yyy of weight www.
It is guaranteed that the given graph is connected (there is a path between any pair of vertices), there are no self-loops (edges connecting the vertex with itself) and multiple edges (for each pair of vertices xxx and yyy, there is at most one edge between this pair of vertices in the graph).
Output
Print one integer — the length of the k−thk-thk−th smallest shortest path in the given graph (paths from the vertex to itself are not counted, paths from iii to jjj and from jjj to iii are counted as one).
Examples
input
6 10 5
2 5 1
5 3 9
6 2 2
1 3 1
5 1 8
6 5 10
1 6 5
6 4 6
3 6 2
3 4 5
output
3
input
7 15 18
2 6 3
5 7 4
6 5 4
3 6 9
6 7 7
1 6 4
7 1 6
7 2 1
4 3 2
3 2 8
5 3 6
2 5 5
3 7 9
4 1 8
2 1 1
output
9
题意
- 给你一张图,求所有点对的最短路径第kkk小,uuu到vvv最短路径路径与vvv到uuu路径只算一次,k≤400k\leq 400k≤400
题解
- 看到kkk这么小,自然想到暴力搞,对!只需要取出前kkk小的边进行路径压缩就行了,然后暴力将这些所有最短路径排序,输出第kkk大,至于为什么不需要第k+1k+1k+1大的边呢?都第k+1k+1k+1大了还要它干嘛?
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=5e5+10;
#define inf 0x3f3f3f3f3f3f3f3f
long long dp[805][805],dis[maxn];
int tot=0,n,m,k,b[maxn],cnt=0;
struct node{
int u,v,w;
friend bool operator<(const node&a,const node&b){
return a.w<b.w;
}
}a[maxn];
int main()
{
scanf("%d %d %d",&n,&m,&k);
for(int i=1;i<=m;i++) scanf("%d %d %d",&a[i].u,&a[i].v,&a[i].w);
sort(a+1,a+m+1);memset(dp,0x3f,sizeof(dp));
for(int i=1;i<=min(k,m);i++) b[++cnt]=a[i].u,b[++cnt]=a[i].v;
sort(b+1,b+cnt+1);int qwq=unique(b+1,b+cnt+1)-b-1;
for(int i=1;i<=min(k,m);i++) {
int from=lower_bound(b+1,b+qwq+1,a[i].u)-b,to=lower_bound(b+1,b+qwq+1,a[i].v)-b;
dp[from][to]=dp[to][from]=a[i].w;
}
for(int k=1;k<=qwq;k++) for(int i=1;i<=qwq;i++) for(int j=1;j<=qwq;j++)if(dp[i][k]+dp[k][j]<dp[i][j]) dp[i][j]=dp[i][k]+dp[k][j];
for(int i=1;i<=qwq;i++) for(int j=i+1;j<=qwq;j++) if(dp[i][j]!=inf) dis[++tot]=dp[i][j];
sort(dis+1,dis+tot+1);
printf("%lld\n",dis[k]);
}