链接:https://www.nowcoder.com/acm/contest/203/I
来源:牛客网
Metropolis
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 524288K,其他语言1048576K
64bit IO Format: %lld
题目描述
魔方国有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的答案。
示例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
题意:给出一张图,其中有p个点,求p个点中每个点到其他p-1个点中的最短距离的点的距离。
思路:多源多汇最短路,把dijkstra变种一下,p个原点push入优先队列中。对于每一个节点,我们记录它是由哪一个源点扩展出来的。当从一个源点i,扩展到另一个源点j扩展出来的一个节点u时,那么dis(i,j)=min(dis(i,j),dis[u]+dis[v]+w)dis(i,j)=min(dis(i,j),dis[u]+dis[v]+w)。
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
#include<fstream>
#include<string.h>
using namespace std;
typedef long long ll;
const ll INF=1e17;
const int MAXN=1000010;
struct qnode
{
int v;
ll c;
int par;
qnode(int _v=0,ll _c=0,int _par = 0):v(_v),c(_c),par(_par){}
bool operator <(const qnode &r)const
{
return c>r.c;
}
};
struct Edge
{
int v;
ll cost;
Edge(int _v=0,ll _cost=0):v(_v),cost(_cost){}
};
vector<Edge> E[MAXN];
bool vis[MAXN];
ll dist[MAXN];
int fa[MAXN];
int bigcity[MAXN];
int mp[MAXN];
ll ans[MAXN];
int p;
void Dijkstra(int n)//点的编号从1开始
{
memset(vis,false,sizeof(vis));
memset(fa,-1,sizeof(fa));
for(int i=1;i<=n;i++) dist[i]=INF;
for(int i = 0;i<p;i++)ans[i] = INF;
priority_queue<qnode> que;
while(!que.empty()) que.pop();
for(int i = 0;i<p;i++)
{
dist[bigcity[i]] = 0;
que.push(qnode(bigcity[i],0,-1));
}
qnode tmp;
while(!que.empty())
{
tmp=que.top();
que.pop();
int u=tmp.v;
int par = (tmp.par==-1?u:tmp.par);
if(dist[u]<tmp.c) continue;
vis[u]=true;
fa[u] = par;
for(int i=0;i<E[u].size();i++)
{
int v=E[u][i].v;
int cost=E[u][i].cost;
if(dist[v]>dist[u]+cost)
{
dist[v]=dist[u]+cost;
fa[v] = par;
que.push(qnode(v,dist[v],par));
}
else if(fa[v]!=par)
{
ans[mp[par]] = min(ans[mp[par]],dist[u]+dist[v]+cost);
if(fa[v]!=-1)
{
ans[mp[fa[v]]] = min(ans[mp[fa[v]]],dist[u]+dist[v]+cost);
}
}
}
}
}
void addedge(int u,int v,ll w)
{
E[u].push_back(Edge(v,w));
}
int main()
{
for(int i=0;i<=MAXN;i++)
if(!E[i].empty())
E[i].clear();
int n;
cin>>n;
int e;
cin>>e;
cin>>p;
memset(mp,-1,sizeof(mp));
for(int i = 0;i<p;i++)
{
cin>>bigcity[i];
mp[bigcity[i]] = i;
}
int u,v;
ll w;
for(int i=1;i<=e;i++)
{
cin>>u>>v>>w;
addedge(u,v,w);
addedge(v,u,w);
}
Dijkstra(n);
for(int i=0;i<p;i++)
cout<<ans[i]<<" ";
cout<<endl;
return 0;
}