首页 > 其他 > 详细

Codeforces 938D Buy a Ticket (转化建图 + 最短路)

时间:2018-02-20 00:02:54      阅读:300      评论:0      收藏:0      [点我收藏+]

题目链接  Buy a Ticket

题意   给定一个无向图。对于每个$i$ $\in$ $[1, n]$, 求$min\left\{2d(i,j) + a_{j}\right\}$

建立超级源点$n+1$, 对于每一条无向边$(x, y, z)$,$x$向$y$连一条长度为$2z$的边,反之亦然。

对于每个$a_{i}$, 从$i$到$n+1$连一条长度为$a_{i}$的边,反之亦然。

然后跑一边最短路即可。

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define dec(i, a, b)	for (int i(a); i >= (b); --i)
#define MP		make_pair
#define fi		first
#define se		second


typedef long long LL;

const int N = 2e5 + 10;

int n, m;
LL dis[N];

struct node{
	int u;
	LL w;
	friend bool operator < (const node &a, const node &b){
		return a.w > b.w;
	}
};

vector <node> v[N];

void dij(int s, LL dis[], vector <node> v[]){
	priority_queue <node> q;
	static bool vis[N];
	rep(i, 1, n) dis[i] = 1e18, vis[i] = false;
	q.push({s, 0});
	dis[s] = 0;
	while (!q.empty()){
		int u = q.top().u; q.pop();
		if (vis[u]) continue;
		vis[u] = 1;
		for (auto edge : v[u]) if (dis[u] + edge.w < dis[edge.u]){
			dis[edge.u] = dis[u] + edge.w;
			q.push({edge.u, dis[edge.u]});
		}
	}
}


int main(){

	scanf("%d%d", &n, &m);
	rep(i, 1, m){
		int x, y;
		LL z;
		scanf("%d%d%lld", &x, &y, &z);
		v[x].push_back({y, z * 2});
		v[y].push_back({x, z * 2});
	}

	rep(i, 1, n){
		LL x;
		scanf("%lld", &x);
		v[n + 1].push_back({i, x});
		v[i].push_back({n + 1, x});
	}

	dij(n + 1, dis, v);
	rep(i, 1, n) printf("%lld ", dis[i]);
	return 0;
}

 

  

 

Codeforces 938D Buy a Ticket (转化建图 + 最短路)

原文:https://www.cnblogs.com/cxhscst2/p/8454662.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!