码迷,mamicode.com
首页 > 其他好文 > 详细

CODEVS 1036 商务旅行

时间:2016-08-10 18:51:27      阅读:228      评论:0      收藏:0      [点我收藏+]

标签:

题目描述 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 商务旅行

标签:

原文地址:http://www.cnblogs.com/gzhonghui/p/5757799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!