CodeForces - 938D Buy a Ticket 建源点

题目链接:点击查看

题意:n个城市,m条路,每条路都有自己的花费,每个城市看演唱会也有自己的花费,问从每一个城市到另一个城市(或就在自己城市)看演唱会的最小花费,到其他城市看完再回来。

题解:建一个源点,源点到其他点的距离就为该城市的演唱会的门票话费,从原点跑一边最短路即可,细想一下,太强了

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=3e5+10;
struct edge{
	int to,nex;
	ll d;
}e[N*2];
int head[N],len,vis[N];
ll dis[N];
int n,m;
struct node{
	int to;
	ll d;
	node(){
	}
	node(int to_,ll d_)
	{
		to=to_;
		d=d_;
	}
	bool operator <(const node &xx)const
	{
		return d>xx.d;
	}
};
void add(int x,int y,ll z)
{
	e[len].to=y;
	e[len].d=z;
	e[len].nex=head[x];
	head[x]=len++;
}
void DIJ()
{
	node now;
	priority_queue<node> q;
	dis[0]=0;
	vis[0]=1;
	q.push(node(0,0));
	int to;
	while(!q.empty())
	{
		now=q.top();q.pop();
		vis[now.to]=0;
	//	cout<<now.to<<endl;
		for(int i=head[now.to];i!=-1;i=e[i].nex)
		{
			to=e[i].to;
	//		cout<<to<<" "<<now.to<<endl;
			if(dis[to]>dis[now.to]+e[i].d)
			{
				
				dis[to]=dis[now.to]+e[i].d;
				if(!vis[to])
				{
					vis[to]=1;
					q.push(node(to,dis[to]));
				}
			}
		}
	}
}
int main()
{
	
	scanf("%d%d",&n,&m);
	for(int i=0;i<=n;i++)
	{
		head[i]=-1;
		dis[i]=1e18;
	}
	int x,y;
	ll z;
	for(int i=1;i<=m;i++)
	{
		scanf("%d%d%lld",&x,&y,&z);
		add(x,y,z*2);
		add(y,x,z*2);	
	} 
	for(int i=1;i<=n;i++)
	{
		scanf("%lld",&z);
		add(0,i,z);
	}
	DIJ(); 
	for(int i=1;i<=n;i++)
		printf("%lld%c",dis[i]," \n"[i==n]);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/mmk27_word/article/details/88767430
今日推荐