传送门:http://codeforces.com/problemset/problem/1196/F
好不容易div3做出了最后一题,结果B题不知道WA哪了,巨惨,而且前期A题看不懂,B题WA,C题WA,排名巨低
K只有400,那么我们一开始只需要加400条最小的边进图,那么涉及到的点最多就800.
吧这些点拿出来在新建的图上跑spfa,跑出来所有的结果丢进ans数组里
排序然后输出第k小
#include<bits/stdc++.h>
#define maxl 200010
using namespace std;
const long long inf=1ll<<62;
int n,m,k,cnt,nn;
int ehead[maxl];
long long dis[maxl];
struct edg
{
int u,v,l;
}edge[maxl];
struct ed
{
int to,nxt,l;
}e[maxl];
bool in[maxl];
queue <int> q;
vector <int>vex,tmp;
vector <long long> ans;
inline bool cmp(const edg &x,const edg &y)
{
return x.l<y.l;
}
inline void add(int u,int v,int l)
{
vex.push_back(u);vex.push_back(v);
e[++cnt].to=v;e[cnt].nxt=ehead[u];e[cnt].l=l;ehead[u]=cnt;
e[++cnt].to=u;e[cnt].nxt=ehead[v];e[cnt].l=l;ehead[v]=cnt;
}
inline void prework()
{
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=m;i++)
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].l);
sort(edge+1,edge+1+m,cmp);
int len=min(k,m);
cnt=0;
for(int i=1;i<=len;i++)
add(edge[i].u,edge[i].v,edge[i].l);
}
inline void spfa(int d)
{
int u,v;while(!q.empty())q.pop();
for(int i=0;i<nn;i++)
dis[vex[i]]=inf,in[vex[i]]=false;
q.push(vex[d]);
dis[vex[d]]=0;in[vex[d]]=true;
while(!q.empty())
{
u=q.front();q.pop();in[u]=false;
for(int i=ehead[u];i;i=e[i].nxt)
{
v=e[i].to;
if(dis[v]>dis[u]+e[i].l)
{
dis[v]=dis[u]+e[i].l;
if(!in[v])
{
q.push(v);
in[v]=true;
}
}
}
}
for(int i=0;i<nn;i++)
if(vex[i]>vex[d] && dis[vex[i]]<inf)
ans.push_back(dis[vex[i]]);
}
inline void mainwork()
{
sort(vex.begin(),vex.end());
vex.erase(unique(vex.begin(),vex.end()),vex.end());
nn=vex.size();
for(int i=0;i<nn;i++)
spfa(i);
sort(ans.begin(),ans.end());
}
inline void print()
{
printf("%lld",ans[k-1]);
}
int main()
{
prework();
mainwork();
print();
return 0;
}