【codevs 1036】商務旅行

來源:互聯網
上載者:User

1036 商務旅行
時間限制: 1 s
空間限制: 128000 KB
題目等級 : 鑽石 Diamond
題解
題目描述 Description
某首都城市的商人要經常到各城鎮去做生意,他們按自己的路線去做,目的是為了更好的節約時間。

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

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

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

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

範例輸入 Sample Input
5
1 2
1 5
3 5
4 5
4
1
3
2
5
範例輸出 Sample Output
7

資料範圍及提示 Data Size & Hint

沒有環QAQ
整張圖n個點 n-1條邊
所以這是棵樹

一棵樹上的兩個點會是什麼關係。
看下圖↓

第一種 點2和點4,點3和點7這種 在同一條鏈上的
第二種 點4和點5,點5和點6這種 隔了十萬八千裡的

對於第一種直接走過去就好啦
對於第二種 查詢公用祖先~
用點4和點5舉個例子
就是 4的深度 + 5的深度 - 2 * 2的深度

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 70005;int n,m,qq,tot = 0;int f,t,x,ans = 0,now = 1;int first[MAXN],next[MAXN];int fa[MAXN][35],deep[MAXN];struct edge{    int f,t;}l[MAXN];void init(){    memset(first,0xff,sizeof(first));    tot = 0;    return;}void build(int f,int t){    l[++ tot] = (edge){f,t};    next[tot] = first[f];    first[f] = tot;    return;}void dfs(int x,int f){    fa[x][0] = f;    deep[x] = deep[f] + 1;    for(int i = first[x]; i != -1; i = next[i])        if(l[i].t != f) dfs(l[i].t,x);    return;}void make_fa(){    for(int j = 1; j <= 20; j ++)        for(int i = 1; i <= n; i ++)            fa[i][j] = fa[fa[i][j - 1]][j - 1];    return;}int lca(int x,int y){    if(deep[x] < deep[y])   swap(x,y);    for(int j = 20; j >= 0; j --)        if(deep[fa[x][j]] >= deep[y])            x = fa[x][j];    if(x == y)  return x;    for(int j = 20; j >= 0;j --)        if(fa[x][j] != fa[y][j])            x = fa[x][j],y = fa[y][j];    return fa[x][0];}int ask(int x,int y){    return deep[x] + deep[y] - (deep[lca(x,y)] << 1);}int main(){    init();    scanf("%d",&n);    for(int i = 1; i < n; i ++)    {        scanf("%d %d",&f,&t);        build(f,t),build(t,f);    }    deep[0] = -1;    dfs(1,0);    make_fa();    scanf("%d",&qq);    while(qq --)    {        scanf("%d",&x);        ans += ask(now,x);        now = x;    }    printf("%d\n",ans);    return 0;}
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.