倍增法-lca codevs 1036 商務旅行

來源:互聯網
上載者:User

標籤:

codevs 1036 商務旅行 時間限制: 1 s 空間限制: 128000 KB 題目等級 : 鑽石 Diamond題目描述  Description

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

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

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

輸入描述  Input Description

輸入檔案中的第一行有一個整數N,1<=n<=30 000,為城鎮的數目。下面N-1行,每行由兩個整數a 和b (1<=ab<=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

 1 #define N 60100 2 #include<iostream> 3 using namespace std; 4 #include<cstdio> 5 #include<cstring> 6 #define C 20 7 typedef long long ll; 8 int ance[N>>1][C],dis[N>>1],n,a,b,m; 9 ll sum=0;10 struct Edge{11     int v,last;12 }edge[N<<1];13 int deep[N>>1],head[N>>1],t=0;14 void add_edge(int u,int v)15 {16     ++t;17     edge[t].v=v;18     edge[t].last=head[u];19     head[u]=t;20 }21 void input()22 {23     scanf("%d",&n);24     for(int i=1;i<n;++i)25     {26         scanf("%d%d",&a,&b);27         add_edge(a,b);28         add_edge(b,a);/*注意樹上建邊必須是雙向的*/29     }30 }31 void dfs(int k)32 {33     for(int l=head[k];l;l=edge[l].last)34     {35         if(!deep[edge[l].v])36         {37             dis[edge[l].v]=dis[k]+1;38             ance[edge[l].v][0]=k;39             deep[edge[l].v]=deep[k]+1;40             dfs(edge[l].v);41         }42     }43 }44 void chuli_ance()45 {46     for(int i=1;(1<<i)<=n;++i)47       for(int j=1;j<=n;++j)48       ance[j][i]=ance[ance[j][i-1]][i-1];49 }50 int lca(int a,int b)51 {52     int i,j;53     if(deep[a]<deep[b]) swap(a,b);54     for(i=0;(1<<i)<=deep[a];++i);55       i--;56     for(j=i;j>=0;--j)57       if(deep[a]-(1<<j)>=deep[b])58       a=ance[a][j];59     if(a==b) return a;60     for(j=i;j>=0;--j)61     {62         if(ance[a][j]!=-1&&ance[a][j]!=ance[b][j])63         {64             a=ance[a][j];65             b=ance[b][j];66         }67     }68     return ance[a][0];69 }70 int main()71 {72     input();73     deep[1]=1;74     dis[1]=0;75     memset(ance,-1,sizeof(ance));76     dfs(1);77     chuli_ance();78     scanf("%d",&m);79     scanf("%d",&a);80     int sta=a;81     for(int i=2;i<=m;++i)82     {83         scanf("%d",&b);84         int zuxian=lca(a,b);85         sum+=(dis[a]+dis[b]-2*dis[zuxian]);86         a=b;87     }88     sum+=dis[sta];89     cout<<sum<<endl;90     return 0;91 }

 

倍增法-lca codevs 1036 商務旅行

相關文章

聯繫我們

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