列表

详情


NC19789. 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,b≤ n,1 ≤ l≤ 109)。
保证图是连通的。

输出描述

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

示例1

输入:

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

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 385ms, 内存消耗: 23672K, 提交时间: 2023-01-01 20:10:53

#include<bits/stdc++.h>
#define int long long
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,a,b) for(int i=(a);i< (b);++i)
using namespace std;

const int N=2e5+7,M=N+N,INF=0x3f3f3f3f;
int n,m,p,fa[N],dist[N],st[N],ans[N],temp[N];
int e[M],ne[M],w[M],h[N],idx;

void add(int x,int y,int z)
{
	e[++idx]=y;
	w[  idx]=z;
	ne[ idx]=h[x];
	h[    x]=idx;
}

struct node{
	int id,dist;
	
	bool operator < (const node &W) const
	{
		return dist>W.dist;
	}
};

void dji()
{
	memset(st,0,sizeof st);
	memset(dist,0x3f,sizeof dist);
	
	priority_queue<node> q;
	rep(i,1,p)
	{
		dist[temp[i]]=0;
		q.push({temp[i],0});
	}
	
	while(!q.empty())
	{
		int u=q.top().id; q.pop(); 
		
		if(st[u]) continue;
		st[u]=1;
		
		for(int i=h[u];~i;i=ne[i])
		{
			int j=e[i];
			if(dist[j]>dist[u]+w[i])
			{
				dist[j]=dist[u]+w[i];
				fa[j]=fa[u];
				q.push({j,dist[j]});
			}
			else if(fa[j]!=fa[u])
			{
				ans[fa[u]]=min(ans[fa[u]],dist[j]+dist[u]+w[i]);
				ans[fa[j]]=min(ans[fa[j]],dist[j]+dist[u]+w[i]);
			}
		}
	}
}



signed main()
{
	memset(h,-1,sizeof h);
	cin>>n>>m>>p;
	rep(i,1,p)
	{
		int x; cin>>x;
		ans[x]=LLONG_MAX;
		temp[i]=x;
		fa[x]=x;
	}
	
	rep(i,1,m)
	{
		int x,y,z; cin>>x>>y>>z;
		add(x,y,z); add(y,x,z);  
	}
	
	dji();
	
	rep(i,1,p) cout<<ans[temp[i]]<<" ";
	
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 478ms, 内存消耗: 22992K, 提交时间: 2020-05-04 10:47:30

#pragma GCC optimize("-Ofast","-funroll-all-loops")
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+10,M=N<<1;
int n,m,p,d[N],pre[N],res[N],x[N],vis[N];
int head[N],nex[M],to[M],w[M],tot;
inline void add(int a,int b,int c){to[++tot]=b; nex[tot]=head[a]; w[tot]=c; head[a]=tot;}
void Dijkstra(){
	priority_queue<pair<int,int> > q;	memset(d,0x3f,sizeof d);
	for(int i=1;i<=p;i++)	q.push({0,x[i]}),d[x[i]]=0,pre[x[i]]=x[i];
	while(q.size()){
		int u=q.top().second;	q.pop();
		for(int i=head[u];i;i=nex[i]){
			if(d[to[i]]>d[u]+w[i]){
				d[to[i]]=d[u]+w[i];	q.push({-d[to[i]],to[i]}); pre[to[i]]=pre[u];
			}else if(pre[to[i]]!=pre[u]){
				res[pre[u]]=min(res[pre[u]],w[i]+d[u]+d[to[i]]);
				res[pre[to[i]]]=min(res[pre[to[i]]],w[i]+d[u]+d[to[i]]);
			}
		}
	}
}
signed main(){
	cin>>n>>m>>p;	memset(res,0x3f,sizeof res);
	for(int i=1;i<=p;i++)	scanf("%lld",&x[i]);
	for(int i=1,a,b,c;i<=m;i++)	scanf("%lld %lld %lld",&a,&b,&c),add(a,b,c),add(b,a,c);
	Dijkstra();
	for(int i=1;i<=p;i++)	printf("%lld ",res[x[i]]);
	return 0;
}

C++11(clang++ 3.9) 解法, 执行用时: 389ms, 内存消耗: 28268K, 提交时间: 2020-06-23 19:36:59

#include<bits/stdc++.h>
using namespace std;

struct node
{
	long long x,h;
	bool operator<(const node &a)const
	{
		return a.h<h;
	}
}r,f;
vector<int>R[200005],W[200005];
priority_queue<node>Q;
int n,m,p,P[200005],V[200005];
long long D[200005],ans[200005];
int main()
{
    int i,j,k;
    scanf("%d%d%d",&n,&m,&p);
    for(i=1;i<=n;i++)D[i]=ans[i]=1e18;
    for(i=0;i<p;i++)scanf("%d",&P[i]),r.x=P[i],D[P[i]]=r.h=0,Q.push(r),V[P[i]]=P[i];
    while(m--)
    {
    	scanf("%d%d%d",&i,&j,&k);
    	R[i].push_back(j),R[j].push_back(i);
    	W[i].push_back(k),W[j].push_back(k);
	}
	while(!Q.empty())
	{
		f=Q.top(),Q.pop();
		if(D[f.x]<f.h)continue;
		for(i=0;i<R[f.x].size();i++)
		{
			j=R[f.x][i];
			if(f.h+W[f.x][i]<D[j])r.h=D[j]=f.h+W[f.x][i],r.x=j,Q.push(r),V[j]=V[f.x];
			else if(V[j]!=V[f.x])
			{
				ans[V[f.x]]=min(ans[V[f.x]],D[f.x]+D[j]+W[f.x][i]);
				ans[V[j]]=min(ans[V[j]],D[f.x]+D[j]+W[f.x][i]);
			}
		}
	}
	for(i=0;i<p;i++)printf("%lld ",ans[P[i]]);
    return 0;
}

上一题