题意:
有一张图,n个点,m条边。问你所有最短路中第k大的路径的长度是多少。
题解:
k最大只有400.那么就取长度前k的边,组成一张图,然后暴力400次即可。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=2e5+5;
struct node{
int to,next;
ll v;
}e[N];
struct edge{
int x,y;
ll v;
bool operator<(const edge& a)const
{
return v<a.v;
}
}p[N];
int head[N],cnt;
void add(int x,int y,ll v){
e[cnt].to=y;
e[cnt].next=head[x];
e[cnt].v=v;
head[x]=cnt++;
}
struct point{
int x,y;
ll v;
bool operator< (const point& a)const
{
return v>a.v;
}
};
priority_queue<point>Q;
unordered_map<int,bool>mp[N];
int main()
{
memset(head,-1,sizeof(head));
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++)
scanf("%d%d%lld",&p[i].x,&p[i].y,&p[i].v);
sort(p+1,p+1+m);
for(int i=1;i<=min(m,k);i++)
add(p[i].x,p[i].y,p[i].v),add(p[i].y,p[i].x,p[i].v),Q.push({p[i].x,p[i].y,p[i].v});
for(int i=1;i<=n;i++)
mp[i][i]=1;
while(k){
point u=Q.top();
Q.pop();
if(mp[u.x].count(u.y))
continue;
k--;
//printf("k:%d %d %d %lld\n",k,u.x,u.y,u.v);
if(!k)
return 0*printf("%lld\n",u.v);
for(int i=head[u.x];~i;i=e[i].next){
int ne=e[i].to;
Q.push({ne,u.y,u.v+e[i].v});
}
for(int i=head[u.y];~i;i=e[i].next){
int ne=e[i].to;
Q.push({u.x,ne,u.v+e[i].v});
}
mp[u.x][u.y]=1;
mp[u.y][u.x]=1;
}
}