链接
https://codeforces.com/contest/1196/problem/F
题解
用到的肯定只有前
k
k
k大的边
所以只保留前
k
k
k大的边以及关联的点,最多
2
k
2k
2k个点
在这张图上用
d
i
j
k
s
t
r
a
dijkstra
dijkstra求出两两点之间的最短路
时间复杂度
O
(
k
2
l
o
g
k
)
O(k^2logk)
O(k2logk)
代码
#include<bits/stdc++.h>
#define maxn 200010
#define maxe 400010
#define linf (1ll<<60)
#define iinf 0x3f3f3f3f
#define eps 1e-8
#define cl(x) memset(x,0,sizeof(x))
#define mod 1000000007ll
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
int c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll n, dis[maxn];
struct Graph
{
int etot, head[maxn], to[maxe], next[maxe], w[maxe];
void clear(int N)
{
int i;
for(i=1;i<=N;i++)head[i]=0;
for(i=1;i<=etot;i++)to[i]=next[i]=w[i]=0;
etot=0;
}
void adde(int a, int b, int c){to[++etot]=b;w[etot]=c;next[etot]=head[a];head[a]=etot;}
}G;
ll N, M, K;
struct Dijkatra
{
ll dist[maxn];
priority_queue<pair<ll,ll>> heap;
typedef pair<ll,ll> pr;
void clear(int N, ll opt=-1) //opt=-1表示求最短路,opt=1表示求最长路
{
for(auto i=1;i<=N;i++)dist[i]=opt*linf;
}
void run(Graph& G, ll S, ll opt=-1)
{
heap.emplace(pr(dist[S]=0,S));
while(!heap.empty())
{
pr x;
do x=heap.top(), heap.pop();
while(x.first!=dist[x.second] and !heap.empty());
for(auto p=G.head[x.second];p;p=G.next[p])
{
if(dist[G.to[p]]<dist[x.second]+opt*G.w[p])
{
dist[G.to[p]]=dist[x.second]+opt*G.w[p];
heap.emplace(pr(dist[G.to[p]],G.to[p]));
}
}
}
}
}dij;
struct edge
{
ll u, v, w;
}e[maxn];
int main()
{
ll i, j, k;
N=read(), M=read(), K=read();
for(i=1;i<=M;i++)e[i].u=read(), e[i].v=read(), e[i].w=read();
sort(e+1,e+M+1,[](edge e1, edge e2){return e1.w<e2.w;});
set<ll> st;
for(i=1;i<=K and i<=M;i++)
{
st.emplace(e[i].u);
st.emplace(e[i].v);
}
map<ll,ll> tb;
ll tot=0;
for(auto x:st)tb[x]=++tot;
G.clear(tot);
for(i=1;i<=K and i<=M;i++)
{
if(st.count(e[i].u) and st.count(e[i].v))
{
G.adde(tb[e[i].u],tb[e[i].v],e[i].w);
G.adde(tb[e[i].v],tb[e[i].u],e[i].w);
}
}
vector<ll> lis;
for(i=1;i<=tot;i++)
{
dij.clear(tot);
dij.run(G,i);
for(j=i;j<=tot;j++)if(i<j)lis.emplace_back(dij.dist[j]);
}
for(auto &x:lis)x=-x;
sort(lis.begin(),lis.end());
cout<<lis.at(K-1);
return 0;
}