《商务旅行》解题报告
《商務(wù)旅行》解題報告
by mps
?【題目描述】
? 某首都城市的商人要經(jīng)常到各城鎮(zhèn)去做生意,他們按自己的路線去做,目的是為了更好的節(jié)約時間。
? 假設(shè)有N個城鎮(zhèn),首都編號為1,商人從首都出發(fā),其他各城鎮(zhèn)之間都有道路連接,任意兩個城鎮(zhèn)之間如果有直連道路,在他們之間行駛需要花費單位時間。該國公路網(wǎng)絡(luò)發(fā)達(dá),從首都出發(fā)能到達(dá)任意一個城鎮(zhèn),并且公路網(wǎng)絡(luò)不會存在環(huán)。
? 你的任務(wù)是幫助該商人計算一下他的最短旅行時間。
【輸入描述】
? 輸入文件中的第一行有一個整數(shù)n,1<=n<=30 000,為城鎮(zhèn)的數(shù)目。下面N-1行,每行由兩個整數(shù)a?和b?(1<=a,?b<=n; a<>b)組成,表示城鎮(zhèn)a和城鎮(zhèn)b有公路連接。在第N+1行為一個整數(shù)M,下面的M行,每行有該商人需要順次經(jīng)過的各城鎮(zhèn)編號。
【輸出描述】
? 在輸出文件中輸出商人旅行的最短時間
【輸入樣例】
5
1 2
1 5
3 5
4 5
4
1
3
2
5
【輸出樣例】
7
【分析】
? 數(shù)學(xué)建模:建成一棵樹,求這些點逐個的樹上最短路徑,算法LCA
? 兩個點的最短路徑=D(x)+D(y)-2*D(LCA(x,y))
? D是根到點的最短路徑
? 很明顯,就是該點的深度
? 通過倍增即可求出,然后直接模擬一下就OK了
【代碼】
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 7 const int MaxN=70001; 8 9 int deep[MaxN],p[MaxN][30]; 10 int n,q; 11 12 struct list{ 13 int to,next; 14 }e[MaxN]; 15 int head[MaxN],cnt=0; 16 17 void addedge(int u,int v){ 18 cnt++; 19 e[cnt].to=v; 20 e[cnt].next=head[u]; 21 head[u]=cnt; 22 } 23 24 void init(){ 25 freopen("trip.in","r",stdin); 26 freopen("trip.out","w",stdout); 27 scanf("%d",&n); 28 int i,u,v; 29 for(i=1;i<n;i++){ 30 scanf("%d %d",&u,&v); 31 addedge(u,v); 32 addedge(v,u); 33 } 34 } 35 36 int lca(int u,int v){ 37 if(deep[u]<deep[v])swap(u,v); 38 int c=deep[u]-deep[v],i; 39 for(i=0;i<=23;i++) 40 if((1<<i)&c) 41 u=p[u][i]; 42 for(i=23;i>=0;i--) 43 if(p[u][i]!=p[v][i]){ 44 u=p[u][i]; 45 v=p[v][i]; 46 } 47 if(u==v)return u; 48 else return p[u][0]; 49 } 50 51 void dfs(int u){ 52 int i; 53 for(i=1;i<=23;i++){ 54 if(deep[u]<(1<<i))break; 55 p[u][i]=p[p[u][i-1]][i-1]; 56 } 57 for(i=head[u];i;i=e[i].next) 58 if(!deep[e[i].to]){ 59 deep[e[i].to]=deep[u]+1; 60 p[e[i].to][0]=u; 61 dfs(e[i].to); 62 } 63 } 64 65 void solve(){ 66 scanf("%d",&q); 67 int i,u,v,ans=0,LCA; 68 for(i=1;i<=n;i++) 69 if(!deep[i]){ 70 p[i][0]=i; 71 deep[i]=1; 72 dfs(i); 73 } 74 scanf("%d",&u); 75 for(i=2;i<=q;i++){ 76 scanf("%d",&v); 77 LCA=lca(u,v); 78 ans+=deep[u]+deep[v]-2*deep[LCA]; 79 u=v; 80 } 81 printf("%d",ans); 82 } 83 84 int main(){ 85 init(); 86 solve(); 87 return 0; 88 }?
?
轉(zhuǎn)載于:https://www.cnblogs.com/maopengsen/p/4198663.html
總結(jié)
以上是生活随笔為你收集整理的《商务旅行》解题报告的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。