牛客国庆集训派对Day3: I. Metropolis(dijkstra)

版权声明:本文为博主原创文章,你们可以随便转载 https://blog.csdn.net/Jaihk662/article/details/82933101

 

I. Metropolis

题目描述

魔方国有n座城市,编号为。城市之间通过n-1条无向道路连接,形成一个树形结构。
在若干年之后,其中p座城市发展成了大都会,道路的数量也增加到了m条。
大都会之间经常有贸易往来,因此,对于每座大都会,请你求出它到离它最近的其它大都会的距离。

输入描述:

第一行三个整数n,m,p (1 ≤ n,m ≤ 2*105,2 ≤ p ≤ n),第二行p个整数表示大都会的编号 (1≤ xi≤ n)。接下来m行每行三个整数ai,bi,li表示一条连接ai和bi,长度为li的道路 (1 ≤ ai,bi ≤ n,1 ≤ li ≤ 109)。
保证图是连通的。

输出描述:

输出一行p个整数,第i个整数表示xi的答案。

输入

5 6 3
2 4 5
1 2 4
1 3 1
1 4 1
1 5 4
2 3 1
3 4 3

输出

3 3 5

只需要求每个大都会离它最近的大都会的最短路!!

那么只用将所有大都会同时设为起点,之后按照dijkstra的规则加边,如果加完某条边后其中两个大都会联通了,更新下答案即可

这样因为每条边最多只会被加一次,所以复杂度是O(mlogn)的

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<math.h>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
#define LL long long
#define mod 1000000007
typedef struct Road
{
	LL len;
	int x, y, id;
	bool operator < (const Road &b) const
	{
		if(len>b.len)
			return 1;
		return 0;
	}
}Road;
vector<Road> G[200005];
LL dp[200005], ans[200005];
int poi[200005], a[200005], vis[200005];
priority_queue<Road> q;
int main(void)
{
	Road now, temp;
	int x, y, n, m, p, i, j, v;
	scanf("%d%d%d", &n, &m, &p);
	memset(dp, -1, sizeof(dp));
	for(i=1;i<=p;i++)
		scanf("%d", &a[i]);
	for(i=1;i<=m;i++)
	{
		scanf("%d%d%lld", &x, &y, &now.len);
		now.id = i;
		now.x = x, now.y = y, G[x].push_back(now);
		now.x = y, now.y = x, G[y].push_back(now);
	}
	for(i=1;i<=p;i++)
	{
		x = a[i];
		poi[x] = i, dp[x] = 0;
		for(j=0;j<G[x].size();j++)
		{
			q.push(G[x][j]);
			vis[G[x][j].id] = 1;
		}
	}
	while(q.empty()==0)
	{
		now = q.top();
		q.pop();
		if(dp[now.y]==-1)
		{
			dp[now.y] = now.len;
			poi[now.y] = poi[now.x];
			for(i=0;i<G[now.y].size();i++)
			{
				v = G[now.y][i].y;
				temp.x = now.y, temp.y = v;
				if(vis[G[now.y][i].id]==0)
				{
					temp.len = G[now.y][i].len+dp[now.y];
					q.push(temp);
					vis[G[now.y][i].id] = 1;
				}
			}
		}
		else if(poi[now.x]!=poi[now.y])
		{
			//printf("%d %d %d %d\n", now.x, now.y, poi[now.x], poi[now.y]);
			if(ans[poi[now.x]]==0)  ans[poi[now.x]] = now.len+dp[now.y];
			else  ans[poi[now.x]] = min(ans[poi[now.x]], now.len+dp[now.y]);
			if(ans[poi[now.y]]==0)  ans[poi[now.y]] = now.len+dp[now.y];
			else  ans[poi[now.y]] = min(ans[poi[now.y]], now.len+dp[now.y]);
		}
	}
	v = 0;
	for(i=1;i<=n;i++)
	{
		if(ans[i]!=0)
		{
			if(v==1)
				printf(" ");
			printf("%lld", ans[i]);
			v = 1;
		}
	}
	puts("");
	return 0;
}
/*
5 6 2
2 5
1 2 4
1 3 1
1 4 1
1 5 4
2 3 1
3 4 3
*/

猜你喜欢

转载自blog.csdn.net/Jaihk662/article/details/82933101