首页 > 代码库 > codevs1026商务旅行
codevs1026商务旅行
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
#include<iostream>#include<cstdio>#include<cstring>#define maxn 30010#define S 16using namespace std;int n,m,num,head[maxn],fa[maxn][S+5],deep[maxn],p1,p2,ans;struct node{ int from; int to; int next;}e[maxn*2];void add(int from,int to){ e[++num].from=from; e[num].to=to; e[num].next=head[from]; head[from]=num;}void swap(int &a,int &b){ int t=a;a=b;b=t;}void init(){ scanf("%d",&n); int x,y; for(int i=1;i<=n-1;i++) { scanf("%d%d",&x,&y); add(x,y);add(y,x); }}void get_fa(){ for(int j=1;j<=S;j++) for(int i=1;i<=n;i++) fa[i][j]=fa[fa[i][j-1]][j-1];}void Dfs(int now,int from,int c)//每个点所在层数 { fa[now][0]=from; deep[now]=c; for(int i=head[now];i;i=e[i].next) { int v=e[i].to; if(v!=from) Dfs(v,now,c+1); }}int get_same(int a,int t){ for(int i=0;i<16;i++) if(t&(1<<i)) a=fa[a][i]; return a; /* if(deep[f[a][i]]>deep[t]) a=f[a][i]; */int LCA(int a,int b){ if(deep[a]<deep[b]) swap(a,b);//保证a深度大 a=get_same(a,deep[a]-deep[b]);//得到a向上deep[a]-deep[b]层是谁 即a的与b同层的祖先是谁 if(a==b) return a;//如果汇聚到一个点 就不用往上了怎么不理我了?不赞同吗? for(int i=S;i>=0;i--)//从最大值开始循环 一开始 fa[a][i] fa[b][i]一定是相等的 //因为此时位于他们lca之上 然后往下 这里可以覆盖每一层 { if(fa[a][i]!=fa[b][i]) { a=fa[a][i]; b=fa[b][i]; } } return fa[a][0];}int main(){ init(); Dfs(1,1,0); get_fa(); scanf("%d%d",&m,&p1); for(int i=1;i<=m-1;i++) { scanf("%d",&p2); int anc=LCA(p1,p2); ans+=deep[p1]+deep[p2]-2*deep[anc]; p1=p2; } printf("%d\n",ans); return 0;}
codevs1026商务旅行
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。