交通运输线(LCA)

题目大意:

战后有很多城市被严重破坏,我们需要重建城市。然而,有些建设材
料只能在某些地方产生。因此,我们必须通过城市交通,来运送这些
材料的城市。由于大部分道路已经在战争期间完全遭到破坏,可能有
两个城市之间没有道路。当然在运输线中,更不可能存在圈。
现在,你的任务来了。给你战后的道路情况,我们想知道,两个城市
之间是否存在道路,如果存在,输出这两个城市之间的最短路径长度

【输入】
第一行一个整数 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\n",res[i]);
109             else
110                 printf("Not connected\n");
111         }
112     }
113 }

 

posted @ 2017-07-28 18:44  Yeader  阅读(374)  评论(0编辑  收藏  举报