codevs 1036 商務旅行(Targin求LCA)

來源:互聯網
上載者:User

標籤:memset   div   its   網路   n+1   output   std   des   檔案中   

傳送門

Description

某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。

假設有N個城鎮,首都編號為1,商人從首都出發,其他各城鎮之間都有道路串連,任意兩個城鎮之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網路發達,從首都出發能到達任意一個城鎮,並且公路網路不會存在環。

你的任務是協助該商人計算一下他的最短旅行時間。

Input

輸入檔案中的第一行有一個整數N,1<=n<=30 000,為城鎮的數目。下面N-1行,每行由兩個整數a 和b (1<=ab<=n; a<>b)組成,表示城鎮a和城鎮b有公路串連。在第N+1行為一個整數M,下面的M行,每行有該商人需要順次經過的各城鎮編號。

Output

在輸出檔案中輸出該商人旅行的最短時間。

Sample Input

5
1 2
1 5
3 5
4 5
4
1
3
2
5

Sample Output
7
思路

  很裸的最近公用祖先的題目,跑一遍spfa記錄首都到各個城市的距離,然後找到兩點的最近公用祖先,這樣就可以根據距離以及最近公用祖先算出兩點的最短路了。

#include<bits/stdc++.h>using namespace std;const int maxn = 30005;int tot = 0,road[maxn],dis[maxn],flag[maxn],vis[maxn],head[maxn],fa[maxn],ancestor[maxn];struct Edge{int to,next;}edge[maxn<<1];int tt = 0,h[maxn],answer[maxn];struct Query{int q,next;int index;}qry[maxn<<1];void init(int N){for (int i = 0;i <= N;i++){fa[i] = i;ancestor[i] = 0;vis[i] = false;head[i] = h[i] = -1;}}void addedge(int u,int v){edge[tot] = (Edge){v,head[u]};head[u] = tot++;}void add_query(int u,int v,int index){qry[tt] = (Query){v,h[u],index};h[u] = tt++;qry[tt] = (Query){u,h[v],index};h[v] = tt++;}void spfa(){queue<int>que;memset(dis,0x3f,sizeof(dis));memset(flag,false,sizeof(flag));que.push(1);dis[1] = 0;flag[1] = true;while (!que.empty()){int u = que.front();que.pop();flag[u] = false;for (int i = head[u];i != -1;i = edge[i].next){int v = edge[i].to;if (dis[u] + 1 < dis[v]){dis[v] = dis[u] + 1;if (!flag[v]){que.push(v);flag[v] = true;}}}}}int find(int x){int r = x;while (r != fa[r])r = fa[r];int i = x,j;while (i != r){j = fa[i];fa[i] = r;i = j;}return r;}void Union(int x,int y){x = find(x),y = find(y);if (x == y)return;fa[y] = x;}void targin_LCA(int u){ancestor[u] = u;vis[u] = true;for (int i = head[u]; i != -1;i = edge[i].next){int v = edge[i].to;if (vis[v])continue;targin_LCA(v);Union(u,v);ancestor[find(u)] = u;}for (int i = h[u];i != -1;i = qry[i].next){int v = qry[i].q;if (vis[v]){answer[qry[i].index] = ancestor[find(v)];}}}int main(){int N,M,u,v,sum = 0;scanf("%d",&N);init(N);for (int i = 1;i < N;i++){scanf("%d%d",&u,&v); addedge(u,v);addedge(v,u);}spfa();scanf("%d",&M);scanf("%d",&road[0]);for (int i = 1;i < M;i++)scanf("%d",&road[i]),add_query(road[i-1],road[i],i);targin_LCA(1);for (int i = 1;i < M;i++){sum += dis[road[i]] + dis[road[i-1]] - 2*dis[answer[i]];}printf("%d\n",sum);return 0;}

  

codevs 1036 商務旅行(Targin求LCA)

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.