# HDU2874(Connections between cities)

Connections between cities

Problem Description
After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, some materials needed can only be produced in certain places. So we need to transport these materials from city to city. For most of roads had been totally destroyed during the war, there might be no path between two cities, no circle exists as well.
Now, your task comes. After giving you the condition of the roads, we want to know if there exists a path between any two cities. If the answer is yes, output the shortest path between them.

Input
Input consists of multiple problem instances.For each instance, first line contains three integers n, m and c, 2<=n<=10000, 0<=m<10000, 1<=c<=1000000. n represents the number of cities numbered from 1 to n. Following m lines, each line has three integers i, j and k, represent a road between city i and city j, with length k. Last c lines, two integers i, j each line, indicates a query of city i and city j.

Output
For each problem instance, one line for each query. If no path between two cities, output “Not connected”, otherwise output the length of the shortest path between them.

Sample Input
5 3 2
1 3 2
2 4 3
5 2 3
1 4
4 5

Sample Output
Not connected
6

#### 思路

1. 先预处理这张图，对于联通的点用并查集维护然后去dfs得到一颗深度优先生成树
2. 对于查询的两个点，如果不在同一颗树根下那么不连通直接用并查集查询
3. 对于查询的两个点做LCA。这两点之间的距离可以转化为这两个点到根节点的距离 减掉 2倍的LCA到根节点的距离。
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
const int maxn = 10005;
const int maxd = 19;
struct edge{
int to;
int w;
int next;
}e[maxn<<1];
int f[maxn][20];
int s[maxn];
bool vis[maxn];
int dist[maxn];
int dep[maxn];
int tot;
void clear_set()
{
tot = 0;
memset(dist,0,sizeof(dist));
memset(vis,false,sizeof(vis));
memset(dep,0,sizeof(dep));
memset(f,0,sizeof(f));
for(int i = 0;i < maxn;i++)		s[i] = i;
}
{
e[tot].to = y;
e[tot].w = z;
}
int find_set(int x)
{
if(x != s[x]){
s[x] = find_set(s[x]);
}
return s[x];
}
void dfs(int x,int fx)
{
dep[x] = dep[fx] + 1;vis[x] = true;
f[x][0] = fx;
for(int i = 1;i <= maxd;i++){
f[x][i] = f[f[x][i-1]][i-1];
}
for(int i = head[x];~i;i = e[i].next){
int y = e[i].to;
if(y != fx){
dist[y] = dist[x] + e[i].w;
dfs(y,x);
}
}
}
int LCA(int x,int y)
{
if(dep[x] < dep[y])		swap(x,y);
int d = dep[x] - dep[y];
for(int i = 0;i <= maxd;i++){
if(((1<<i)&d)){
x = f[x][i];
}
}
if(x == y)		return x;
for(int i = maxd;i >= 0;i--){
if(f[x][i] != f[y][i]){
x = f[x][i];
y = f[y][i];
}
}
return f[x][0];
}
int main()
{
int n,m,q;
while(~scanf("%d%d%d",&n,&m,&q)){
clear_set();
int x,y,z;
for(int i = 0;i < m;i++){
scanf("%d%d%d",&x,&y,&z);
int fx = find_set(x);
int fy = find_set(y);
if(fx != fy)	s[fx] = fy;			//维护两个点的连通性
}
for(int i = 1;i <= n;i++){
if(!vis[i]){
dfs(i,0);
}
}
while(q--){
scanf("%d%d",&x,&y);
int fx = find_set(x);
int fy = find_set(y);
if(fx != fy){
printf("Not connected\n");
continue;
}
int t = LCA(x,y);
int ans = dist[x] + dist[y] - 2*dist[t];
printf("%d\n",ans);
}
}
return 0;
}


08-09 298

10-17 1237

09-01 11

11-20 805

10-19 426

08-28 118

09-02 305

11-12 294

04-09 536

02-07 59

08-05 165

05-01 7

09-20 223

10-07 373

07-26 15

03-19 83万+

04-14 62万+

03-13 16万+

03-01 14万+

03-08 5万+

#### 上班一个月，后悔当初着急入职的选择了

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客