牛客國慶集訓派對Day3 I(多源多匯最短路dijkstra變種)
阿新 • • 發佈:2018-12-13
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; }