1. 程式人生 > >牛客國慶集訓派對Day3 I(多源多匯最短路dijkstra變種)

牛客國慶集訓派對Day3 I(多源多匯最短路dijkstra變種)

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;
}