Codeforces - F. K-th Path

mac2025-12-25  10

F. K-th Path

time limit per test2.5 seconds memory limit per test256 megabytes inputstandard input outputstandard output 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 j to 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⋅105, n−1≤m≤min(n(n−1)2,2⋅105), 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 inputCopy 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 outputCopy 3 inputCopy 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 outputCopy 9


题目大意:求所有两点间的第K大路径。

直接暴力必然会TLE,但是由于K比较小,所以我们必然只需要把前K大的边存下来跑最短路,然后就AC了。

对于每个点跑最短路。

因为边很少,每次更新的点也少,所以我们需要把这些点记录一下,来清空,不能每次O(n)去清空,很显然(但是我sb了,直接TLE)。


AC代码:

#pragma GCC optimize(2) #include<bits/stdc++.h> #define int long long using namespace std; const int N=2e5+10; int n,m,k,d[N],flag,vis[N],st[N]; int head[N],nex[N<<1],to[N<<1],w[N<<1],tot; vector<int> res; struct node{ int u,v,w; }t[N]; inline bool cmp(node a,node b){return a.w<b.w;} inline void add(int a,int b,int c){ to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot; } void dijkstra(int x){ priority_queue<pair<int,int> > q; d[x]=0; q.push({0,x}); vector<int> tem; while(q.size()){ int u=q.top().second; q.pop(); if(vis[u]) continue; vis[u]=1; for(int i=head[u];i;i=nex[i]){ if(d[to[i]]>d[u]+w[i]){ d[to[i]]=d[u]+w[i]; st[to[i]]++; if(st[to[i]]==1) tem.push_back(to[i]); if(!vis[to[i]]) q.push({-d[to[i]],to[i]}); } } } for(int i=0;i<tem.size();i++) res.push_back(d[tem[i]]); d[x]=0x3f3f3f3f3f3f3f3f; vis[x]=0; st[x]=0; for(int i=0;i<tem.size();i++) d[tem[i]]=0x3f3f3f3f3f3f3f3f,vis[tem[i]]=0,st[tem[i]]=0; } signed main(){ cin>>n>>m>>k; memset(d,0x3f,sizeof d); for(int i=1;i<=m;i++) scanf("%lld %lld %lld",&t[i].u,&t[i].v,&t[i].w); sort(t+1,t+1+m,cmp); for(int i=1;i<=k&&i<=m;i++) add(t[i].u,t[i].v,t[i].w),add(t[i].v,t[i].u,t[i].w); for(int i=1;i<=n;i++) dijkstra(i); sort(res.begin(),res.end()); cout<<res[k*2-1]<<endl; return 0; }
最新回复(0)