版权声明:这是蒟蒻的BLOG,神犇转载也要吱一声哦~ https://blog.csdn.net/Dream_Lolita/article/details/89453302
【题目】
CC
一幅
个点的图,其中前
个点之间两两有一条长度为
的无向边。除此之外还有
条长度为
的无向边。
求
到所有点的最短路。
【解题思路】
不知道怎么就开始写起了水题。
完全图边比较多,我们缩一缩规模,只需要将前 个点与一个新点 连边 ,其他边照连即可。
复杂度 ,实现上可以将所有边权乘 ,最后除以 ,就可以避免实数了。
【参考代码】
#include<bits/stdc++.h>
#define fi first
#define se second
#define mkp make_pair
using namespace std;
typedef long long ll;
typedef pair<ll,int> pii;
const int N=1e5+10;
int read()
{
int ret=0;char c=getchar();
while(!isdigit(c)) c=getchar();
while(isdigit(c)) ret=ret*10+(c^48),c=getchar();
return ret;
}
void write(ll x){if(x>9)write(x/10);putchar(x%10^48);}
void writesp(ll x){write(x);putchar(' ');}
namespace DreamLolita
{
int n,K,X,m,S,tot;
int head[N],vis[N];
ll dis[N];
priority_queue<pii,vector<pii>,greater<pii> >q;
struct Tway{int v,w,nex;}e[N<<2];
void add(int u,int v,int w)
{
e[++tot]=(Tway){v,w,head[u]};head[u]=tot;
e[++tot]=(Tway){u,w,head[v]};head[v]=tot;
}
void dij()
{
dis[S]=0;q.push(mkp(dis[S],S));
while(!q.empty())
{
int x=q.top().se;q.pop();
if(vis[x])continue; vis[x]=1;
for(int i=head[x];i;i=e[i].nex)
{
int v=e[i].v;
if(!vis[v]) dis[v]=min(dis[v],dis[x]+e[i].w),q.push(mkp(dis[v],v));
}
}
}
void clear()
{
tot=0;
memset(head,0,sizeof(head));memset(dis,0x3f,sizeof(dis));memset(vis,0,sizeof(vis));
}
void solution()
{
clear();
n=read();K=read();X=read();m=read();S=read();
for(int i=1,u,v;i<=m;++i) u=read(),v=read(),add(u,v,read()*2);
for(int i=1;i<=K;++i) add(i,n+1,X);
dij();for(int i=1;i<=n;++i) writesp(dis[i]/2); puts("");
}
}
int main()
{
#ifdef Durant_Lee
freopen("CC_CLIQUED.in","r",stdin);
freopen("CC_CLIQUED.out","w",stdout);
#endif
int T=read();
while(T--) DreamLolita::solution();
return 0;
}