交通运输线(LCA)
生活随笔
收集整理的這篇文章主要介紹了
交通运输线(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 }?
轉載于:https://www.cnblogs.com/fu3638/p/7252086.html
總結
以上是生活随笔為你收集整理的交通运输线(LCA)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 豆丁相机扣款怎么申请退费?
- 下一篇: 7.3 编址与存储相关计算