SSLOJ 1436.赛艇表演【最短路】


题目:

传送门


题意:

给出一张图以及在每个点看表演所要的花费是多少
问对于每个点,在图中选择任意一个点使得到这个点看表演的花费最小


分析:

我们假设出一个虚点 0 0 0,将每个点与虚点相连,以到该点看表演的花费为权值,如此跑一边最短路即可


代码:

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#define LL long long
using namespace std;
inline LL read() {
    
    
    LL d=0,f=1;char s=getchar();
    while(s<'0'||s>'9'){
    
    if(s=='-')f=-1;s=getchar();}
    while(s>='0'&&s<='9'){
    
    d=d*10+s-'0';s=getchar();}
    return d*f;
}
struct node{
    
    
	LL to,next,w;
}e[800005];
LL ls[800005],cnt=0,n=read(),m=read();
void add(LL x,LL y,LL w)
{
    
    
	e[cnt]=(node){
    
    y,ls[x],w};
	ls[x]=cnt++;
	return;
}
struct dui{
    
    
	LL num,w;
	bool operator < (const dui &www) const {
    
    return w>www.w;}
};
LL dis[200005];
void dij(LL s)
{
    
    
	for(LL i=1;i<=n;i++) dis[i]=1000000000000000ll;
	dis[s]=0; 
	priority_queue<dui> q;
	q.push((dui){
    
    s,0});
	while(q.size())
	{
    
    
		LL u=q.top().num,v=q.top().w;
		q.pop();
		if(v!=dis[u]) continue;
		for(LL i=ls[u];~i;i=e[i].next)
		  if(v+e[i].w<dis[e[i].to])
		    dis[e[i].to]=v+e[i].w,q.push((dui){
    
    e[i].to,dis[e[i].to]});
	}
	return;
}
int main()
{
    
    
	memset(ls,-1,sizeof(ls));
	for(LL i=1;i<=m;i++)
	{
    
    
		LL x=read(),y=read(),w=read()*2;
		add(x,y,w);add(y,x,w);
	}
	LL a;
	for(LL i=1;i<=n;i++) a=read(),add(0,i,a),add(i,0,a);
	dij(0);
	for(int i=1;i<=n;i++) printf("%lld ",dis[i]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35786326/article/details/103029838