CODEVS 1036 商務旅行

來源:互聯網
上載者:User

標籤:

題目描述  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

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

 

LCA問題,可以轉化為RMQ問題

dep[]表示節點在樹中的深度

F是歐拉序列,B是歐拉序列節點對應的深度

pos[]表示節點第一次在歐拉序列中出現的位置

LCA(T,u,v)=F[RMQ(B,pos[u],pos[v])]

這裡RMQ要返回座標,而不是具體值,但本題不需要,本題只要得到LCA的深度即可,直接讓RMQ返回具體值即可,所求深度就是這個傳回值

最小值也可以用線段樹維護

 1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 const int maxn=30001; 5 struct node{ 6     int l,r,mmin; 7 }tree[8*maxn]; 8 struct edge{ 9     int go,next;10 }e[2*maxn];11 int dep[maxn],N,end[maxn],ecount=0,count=0,F[2*maxn],B[2*maxn],M,pos[maxn],v[maxn];12 void add(int a,int b){13     e[++ecount].go=b;14     e[ecount].next=end[a];15     end[a]=ecount;16 }17 void buildTree(int f,int x,int d){18     int go;19     dep[x]=d;20     F[++count]=x;21     B[count]=d;22     if(!v[x]){23         pos[x]=count;v[x]=1;24     }25     for(int i=end[x];i;i=e[i].next){26         go=e[i].go;27         if(go!=f){28             buildTree(x,go,d+1);29             F[++count]=x;30             B[count]=d;31         }32     } 33 }34 void init()35 {36     memset(end,0,sizeof(end));37     memset(v,0,sizeof(v));38 }39 void build(int o,int l,int r){40     if(l==r){41         tree[o].l=tree[o].r=l;42         tree[o].mmin=B[l];43         return;44     }45     int m=(l+r)/2;46     build(2*o,l,m);build(2*o+1,m+1,r);47     tree[o].l=l,tree[o].r=r;48     tree[o].mmin=min(tree[o*2].mmin,tree[o*2+1].mmin);49 }50 int query(int o,int l,int r){51     if(l<=tree[o].l&&tree[o].r<=r) return tree[o].mmin;52     int m=(tree[o].l+tree[o].r)/2;53     int ans=1<<30;54     if(l<=m) ans=min(ans,query(2*o,l,r));55     if(m<r) ans=min(ans,query(2*o+1,l,r));56     return ans;57 }58 int main()59 {60     cin>>N;61     init();62     int x,y;63     for(int i=2;i<=N;i++){64         cin>>x>>y;65         add(x,y),add(y,x);66     }67     buildTree(-1,1,0); 68     build(1,1,count);69     //for(int i=1;i<=count;i++) cout<<i<<"F:"<<F[i]<<endl;70     cin>>M;71     int last,ans=0,to;72     cin>>last;73     for(int i=1;i<M;i++){74         cin>>to;75         ans+=dep[last]+dep[to]-2*B[query(1,min(pos[last],pos[to]),max(pos[last],pos[to]))];76         last=to;77     } 78     cout<<ans;79     return 0;80 }

 

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.