题目大意:
战后有很多城市被严重破坏,我们需要重建城市。然而,有些建设材
料只能在某些地方产生。因此,我们必须通过城市交通,来运送这些
材料的城市。由于大部分道路已经在战争期间完全遭到破坏,可能有
两个城市之间没有道路。当然在运输线中,更不可能存在圈。
现在,你的任务来了。给你战后的道路情况,我们想知道,两个城市
之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度
【输入】
第一行一个整数 Case(Case<=10)表示测试数据组数。
每组测试数据第一行三个整数 N,M 和 C(2<=N<=10,000)(0<=M<10,
000) (1<=c<=1000000)共有 N 个城市,现存 M 条边,共有 C 对运
输需求。
接下来 M 行,每行三个整数 A 和 B,D(1<=A,B<=N,A 不等于 B)表
示从 A 到 B 有一条直接的公路,且距离为 D。
最后 C 行,每行两个整数,S 和 T(1<=S,T<=N,S 不等于 T),即询问从 S
到 T 的最短路径长度。
【输出】
共 Case 行,否存在从 S 到 T 的路径,则输出最短路径,否则输出“Not
connected”
解题思路:lca稍微变形
#include<iostream>
#include<cstdio>
#include<vector>
#include<cstring>
using namespace std;
const int N=1e4+; struct node1{
int to,len;
node1(int to,int len){
this->to=to;
this->len=len;
}
};
struct node2{
int to,id;
node2(int to,int id){
this->to=to;
this->id=id;
}
}; vector<node1>ve[N];
vector<node2>que[N];
bool vis[N];//记录是否在树上被访问
bool used[N];//记录节点是否在整张图中被访问
int fa[N];//记录父节点
int res[N];//查询结果
int dis[N];//dis[i]记录点i里根节点距离
int V,E; //初始化
void init(){
for(int i=;i<=V;i++){
fa[i]=i;
ve[i].clear();
que[i].clear();
}
memset(vis,false,sizeof(vis));
memset(res,-,sizeof(res));
} int find(int x){
return x==fa[x]?x:fa[x]=find(fa[x]);
} void Union(int a,int b){
int x=find(a),y=find(b);
if(x!=y){
fa[x]=y;
}
} void lca(int i){
vis[i]=true;
used[i]=true;
for(int j=;j<ve[i].size();j++){
node1 nd=ve[i][j];
//判断该点是否在图中未被访问过
if(!used[nd.to]){
dis[nd.to]=dis[i]+nd.len;
lca(nd.to);
Union(nd.to,i);
}
}
for(int j=;j<que[i].size();j++){
node2 nd=que[i][j];
//判断该点是否在树上被访问过
if(vis[nd.to]&&res[nd.id]==-){
if(nd.to==i)
res[nd.id]=;
else
res[nd.id]=dis[nd.to]+dis[i]-*dis[find(nd.to)];
}
}
} int main(){
int cas;
scanf("%d",&cas);
while(cas--){
int q;
scanf("%d%d%d",&V,&E,&q);
init();
for(int i=;i<=E;i++){
int a,b,d;
scanf("%d%d%d",&a,&b,&d);
ve[a].push_back(node1(b,d));
ve[b].push_back(node1(a,d));
}
for(int i=;i<=q;i++){
int x,y;
scanf("%d%d",&x,&y);
que[x].push_back(node2(y,i));
que[y].push_back(node2(x,i));
} //LCA
for(int i=;i<=V;i++){
if(!used[i]){
memset(vis,false,sizeof(vis));
lca(i);
}
}
//输出查询结果
for(int i=;i<=q;i++){
if(res[i]!=-)
printf("%d\n",res[i]);
else
printf("Not connected\n");
}
}
}