题目大意:
战后有很多城市被严重破坏,我们需要重建城市。然而,有些建设材
料只能在某些地方产生。因此,我们必须通过城市交通,来运送这些
材料的城市。由于大部分道路已经在战争期间完全遭到破坏,可能有
两个城市之间没有道路。当然在运输线中,更不可能存在圈。
现在,你的任务来了。给你战后的道路情况,我们想知道,两个城市
之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度
【输入】
第一行一个整数 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稍微变形
1 #include<iostream> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 using namespace std; 6 const int N=1e4+5; 7 8 struct node1{ 9 int to,len; 10 node1(int to,int len){ 11 this->to=to; 12 this->len=len; 13 } 14 }; 15 struct node2{ 16 int to,id; 17 node2(int to,int id){ 18 this->to=to; 19 this->id=id; 20 } 21 }; 22 23 vector<node1>ve[N]; 24 vector<node2>que[N]; 25 bool vis[N];//记录是否在树上被访问 26 bool used[N];//记录节点是否在整张图中被访问 27 int fa[N];//记录父节点 28 int res[N];//查询结果 29 int dis[N];//dis[i]记录点i里根节点距离 30 int V,E; 31 32 //初始化 33 void init(){ 34 for(int i=1;i<=V;i++){ 35 fa[i]=i; 36 ve[i].clear(); 37 que[i].clear(); 38 } 39 memset(vis,false,sizeof(vis)); 40 memset(res,-1,sizeof(res)); 41 } 42 43 int find(int x){ 44 return x==fa[x]?x:fa[x]=find(fa[x]); 45 } 46 47 void Union(int a,int b){ 48 int x=find(a),y=find(b); 49 if(x!=y){ 50 fa[x]=y; 51 } 52 } 53 54 void lca(int i){ 55 vis[i]=true; 56 used[i]=true; 57 for(int j=0;j<ve[i].size();j++){ 58 node1 nd=ve[i][j]; 59 //判断该点是否在图中未被访问过 60 if(!used[nd.to]){ 61 dis[nd.to]=dis[i]+nd.len; 62 lca(nd.to); 63 Union(nd.to,i); 64 } 65 } 66 for(int j=0;j<que[i].size();j++){ 67 node2 nd=que[i][j]; 68 //判断该点是否在树上被访问过 69 if(vis[nd.to]&&res[nd.id]==-1){ 70 if(nd.to==i) 71 res[nd.id]=0; 72 else 73 res[nd.id]=dis[nd.to]+dis[i]-2*dis[find(nd.to)]; 74 } 75 } 76 } 77 78 int main(){ 79 int cas; 80 scanf("%d",&cas); 81 while(cas--){ 82 int q; 83 scanf("%d%d%d",&V,&E,&q); 84 init(); 85 for(int i=1;i<=E;i++){ 86 int a,b,d; 87 scanf("%d%d%d",&a,&b,&d); 88 ve[a].push_back(node1(b,d)); 89 ve[b].push_back(node1(a,d)); 90 } 91 for(int i=1;i<=q;i++){ 92 int x,y; 93 scanf("%d%d",&x,&y); 94 que[x].push_back(node2(y,i)); 95 que[y].push_back(node2(x,i)); 96 } 97 98 //LCA 99 for(int i=1;i<=V;i++){ 100 if(!used[i]){ 101 memset(vis,false,sizeof(vis)); 102 lca(i); 103 } 104 } 105 //输出查询结果 106 for(int i=1;i<=q;i++){ 107 if(res[i]!=-1) 108 printf("%d ",res[i]); 109 else 110 printf("Not connected "); 111 } 112 } 113 }