「CF1196F」K-th Path【floyd】

本文介绍了一种求解图中所有点对的最短路径第K小的算法,通过预处理前K小的边进行路径压缩,再对所有可能的最短路径进行排序,最后输出第K小的路径长度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

F. K-th Path

time limit per test 2.5 seconds
memory limit per test 256 megabytes
input standard input
output standard output

You are given a connected undirected weighted graph consisting of nnn vertices and mmm edges.

You need to print the k−thk-thkth 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&lt;j≤n)(1\leq i&lt;j \leq n)(1i<jn), then you need to print the k−thk-thkth element in the sorted array consisting of all di,jd_{i,j}di,j, where 1≤i&lt;j≤n1\leq i&lt;j\leq n1i<jn.

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)(2n2105,n1mmin(2n×(n1),2×105),1kmin(2n×(n1),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)(1x,yn,1w109,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-thkth 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小,uuuvvv最短路径路径与vvvuuu路径只算一次,k≤400k\leq 400k400

题解

  • 看到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]);    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值