CF938D Buy a Ticket

CF938D Buy a Ticket

简单最短路练手题。

首先每个点都有自己的点权,根据经验,这肯定是要转边权的。

再看看题目,题目要求求每个人的去看的费用最小值,一般不难想出要跑 nn 遍最短路,但是时间复杂度太高。

所以我们考虑建立一个虚拟原点,由于一开始的点是有点权的,所以我们把虚拟原点向所有的点连边,权值就是对应点的点权了。

这时候我们就可以只跑一边最短路, disdis 数组就是答案了。

注意,由于要来回,所以边的值要双倍。

code:

#include<bits/stdc++.h>
using namespace std;
const int N =1e6+10;
#define int long long
struct node
{
	int v;
	int w;
};
vector<node> g[N<<1]; 
int dis[N];
struct State{
	int u,d;
	bool operator<(const State &s) const {
		return d > s.d;
	}
};
void dijkstra(int s){
	priority_queue<State> que;
	memset(dis,0x3f,sizeof(dis));
	que.push(State{s,0}),dis[s] = 0;
	
	while(!que.empty()){
		int u = que.top().u,d = que.top().d;
		que.pop();
		if (d > dis[u]) continue;
		for (int i = 0;i < g[u].size();++i){
			int v = g[u][i].v,w = g[u][i].w;
			if (dis[u] + w < dis[v]){
				dis[v] = dis[u] + w;
				que.push(State{v,dis[v]});
			}
		}
	}
}
signed main()
{
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		int u,v,w;
		cin>>u>>v>>w;
		g[u].push_back(node{v,w*2});
		g[v].push_back(node{u,w*2});  
	}
	for(int i=1;i<=n;i++)
	{
		int w;
		cin>>w;
		g[0].push_back(node{i,w}); 
	}
	dijkstra(0);
	for(int i=1;i<=n;i++)
		cout<<dis[i]<<" ";
	return 0;
}
posted @   June_Failure  阅读(1)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示