Codeforces Round #575 (Div. 3) F

Codeforces Round #575 (Div. 3)

F - K-th Path

You are given a connected undirected weighted graph consisting of n vertices and m edges.

You need to print the k-th smallest shortest path in this graph (paths from the vertex to itself are not counted, paths from i to j and from jto i are counted as one).

More formally, if d is the matrix of shortest paths, where di,j is the length of the shortest path between vertices i and j (1≤i<j≤n), then you need to print the k-th element in the sorted array consisting of all di,j, where 1≤i<j≤n.

Input

The first line of the input contains three integers n,m and k (2≤n≤2⋅10^5, n−1≤m≤min(n(n−1)2,2⋅10^5), 1≤k≤min(n(n−1)2,400) — the number of vertices in the graph, the number of edges in the graph and the value of k, correspondingly.

Then m lines follow, each containing three integers x, y and w (1≤x,y≤n, 1≤w≤109, x≠y) denoting an edge between vertices x and y of weight w.

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 x and y, there is at most one edge between this pair of vertices in the graph).

Output

Print one integer — the length of the k-th smallest shortest path in the given graph (paths from the vertex to itself are not counted, paths from i to j and from j to i 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

 

题意:题目意思是给你好多边组成一个图,然后问你任意两点之间第K短路是多少。

思路:这里有个优化,可以先对所有边根据边权排个序,如果总边数超过k,只取前k条边建图就好了,

因为求第k短路,后面的边肯定用不上,(可以自己先思考一下)。然后再离散化一下,拿边跑一遍floyd(k最大400,o(n^3)能接受)。

再暴力把所有边取出来,排个序输出第k短路就好了,这是真的暴力,能过还行,所以说要敢于尝试。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cmath>
  4 #include<cstring>
  5 #include<map>
  6 #include<set>
  7 #include<vector>
  8 #include<algorithm>
  9 #include<queue>
 10 #include<unordered_map>
 11 #include<list>
 12 using namespace std;
 13 #define ll long long 
 14 const int mod=1e9+7;
 15 const ll int inf=1e18+7;
 16  
 17 const int maxn=4e5+5;
 18  
 19 typedef struct
 20 {
 21     int u;
 22     int v;
 23     ll int w;
 24 }St;
 25 St sum[maxn];
 26  
 27 bool cmp(const St &a,const St &b)
 28 {
 29     return a.w < b.w;
 30 }
 31  
 32 int n,m,k;
 33  
 34 ll int e[2005][2005];
 35  
 36 void init()
 37 {
 38     for(int i=0;i<=1505;i++)
 39     {
 40         for(int j=0;j<=1505;j++)
 41         {
 42             if(i==j)
 43                 e[i][j]=0;
 44             else
 45                 e[i][j]=inf;
 46         }
 47     }
 48 }
 49  
 50 int main()
 51 {
 52     ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
 53     
 54     init();
 55     
 56     cin>>n>>m>>k;
 57     
 58     vector<ll int>v;
 59     
 60     for(int i=0;i<m;i++)
 61         cin>>sum[i].u>>sum[i].v>>sum[i].w;
 62     
 63     sort(sum,sum+m,cmp);
 64     
 65     for(int i=0;i<min(m,k);i++)
 66     {
 67         v.push_back(sum[i].u);
 68         v.push_back(sum[i].v);
 69     }
 70     
 71     //离散化 
 72     sort(v.begin(),v.end());//排序 
 73     v.erase(unique(v.begin(),v.end()),v.end());//去重 
 74     
 75     int now=v.size();
 76     
 77     for(int i=0;i<min(m,k);i++)
 78     {
 79         sum[i].u=lower_bound(v.begin(),v.end(),sum[i].u)-v.begin()+1;//加一防止点从0开始 
 80         sum[i].v=lower_bound(v.begin(),v.end(),sum[i].v)-v.begin()+1;
 81         
 82         e[sum[i].u][sum[i].v]=sum[i].w;
 83         e[sum[i].v][sum[i].u]=sum[i].w; 
 84         
 85     }
 86     
 87     for(int k=1;k<=now;k++)
 88     {
 89         for(int i=1;i<=now;i++)
 90         {
 91             for(int j=1;j<=now;j++)
 92             {
 93                 if(e[i][k]+e[k][j]<e[i][j])
 94                 {
 95                     e[i][j]=e[i][k]+e[k][j];
 96                 }
 97             }
 98         }
 99     }
100     
101     vector<ll int>edge;
102     
103     for(int i=1;i<=now;i++)
104     {
105         for(int j=i+1;j<=now;j++)
106         {
107             edge.push_back(e[i][j]);
108         }
109     }
110     
111     sort(edge.begin(),edge.end());;
112     
113     cout<<edge[k-1]<<endl;
114     
115     return 0;
116 }
大佬见笑,,
原文地址:https://www.cnblogs.com/xwl3109377858/p/11272219.html