多源对多源最短路
Posted spnooyseed
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多源对多源最短路相关的知识,希望对你有一定的参考价值。
https://ac.nowcoder.com/acm/contest/6116/B
魔方国有n座城市,编号为1sim n1~n。城市之间通过n-1条无向道路连接,形成一个树形结构。
在若干年之后,其中p座城市发展成了大都会,道路的数量也增加到了m条。
大都会之间经常有贸易往来,因此,对于每座大都会,请你求出它到离它最近的其它大都会的距离。
蒟蒻第一次见多源对多源最短路,没想到是这种处理方式。
- 第一步就是按照正常加一个虚点连接所有的大都会,距离为0然后跑一边dijkstra , 同时记录当前这个点距离哪个大都会最近。
- 当前u点最近的大都会from[u] , v点最近的大都会from[v] ,
如果他们from[u] = from[v] , 那也就是u 和 v两点由同一个点拓展而出 , 否则的话由两个点拓展而出的时候,就可以算一下这两个拓展点之间的最短距离 ,,
那么其中一个大都会距离另一个大都会的最短距离可更新为ans = min(ans , dis[u] + dis[v] + w )
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <unordered_map>
#include <vector>
#include <map>
#include <list>
#include <queue>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <stack>
#include <set>
#pragma GCC optimize(3 , "Ofast" , "inline")
using namespace std ;
#define ios ios::sync_with_stdio(false) , cin.tie(0) , cout.tie(0)
#define x first
#define y second
typedef long long ll ;
const double esp = 1e-6 , pi = acos(-1) ;
typedef pair<ll , ll> PII ;
const int N = 1e6 + 10 , INF = 0x3f3f3f3f , mod = 1e9 + 7;
ll in()
{
ll x = 0 , f = 1 ;
char ch = getchar() ;
while(!isdigit(ch)) {if(ch == ‘-‘) f = -1 ; ch = getchar() ;}
while(isdigit(ch)) x = x * 10 + ch - 48 , ch = getchar() ;
return x * f ;
}
int e[N] , ne[N] , h[N] , n , m , p , idx , a[N] , vis[N] , from[N] ;
ll dis[N] , ans[N] , w[N] ;
void add(int a , int b , int c)
{
e[idx] = b , ne[idx] = h[a] , w[idx] = c , h[a] = idx ++ ;
}
int main()
{
memset(h , -1 , sizeof h) ;
n = in() , m = in() , p = in() ;
for(int i = 1; i <= p ;i ++ ) a[i] = in() ;
for(int i = 1 , a , b , c ; i <= m ;i ++ )
a = in() , b = in() , c = in() , add(a , b , c) , add(b , a , c) ;
for(int i = 1 ; i <= n ;i ++ ) ans[i] = dis[i] = 1e18 ;
priority_queue<PII , vector<PII> , greater<PII> > q ;
for(int i = 1; i <= p ;i ++ )
q.push({0 , a[i]}) , dis[a[i]] = 0 , from[a[i]] = a[i] ;
while(q.size())
{
auto t = q.top() ;q.pop() ;
if(vis[t.second]) continue ;
vis[t.second] = 1 ;
int u = t.second ;
for(int i = h[u] ; ~i ; i = ne[i])
{
int v = e[i] ;
if(dis[v] > dis[u] + w[i])
dis[v] = dis[u] + w[i] , from[v] = from[u] , q.push({dis[v] , v}) ;
else if(from[v] != from[u])
{
ll t = dis[u] + dis[v] + w[i] ;
ans[from[v]] = min(ans[from[v]] , t) ;
ans[from[u]] = min(ans[from[u]] , t) ;
}
}
}
for(int i = 1; i <= p ;i ++ ) cout << ans[a[i]] << " " ;
puts("") ;
return 0 ;
}
/*
*/
以上是关于多源对多源最短路的主要内容,如果未能解决你的问题,请参考以下文章