商务旅行
题目描述 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
思路:裸的LCA
代码实现:
1 #include<cstdio> 2 const int maxn=30010; 3 int n,m,ans; 4 int a,b,c; 5 int h[maxn],hs=1; 6 struct edge{int s,n;}e[maxn<<1]; 7 void add(int q,int z){e[++hs]=(edge){z,h[q]},h[q]=hs;} 8 int f[maxn],d[maxn]; 9 void dfs(int k,int fa,int de){ 10 f[k]=fa,d[k]=de; 11 for(int i=h[k];i;i=e[i].n) 12 if(e[i].s!=fa) dfs(e[i].s,k,de+1); 13 } 14 int main(){ 15 scanf("%d",&n); 16 for(int i=1;i<n;i++){ 17 scanf("%d%d",&a,&b); 18 add(a,b),add(b,a); 19 } 20 dfs(1,0,1); 21 scanf("%d%d",&m,&a); 22 for(int i=1;i<m;i++){ 23 scanf("%d",&b),c=b; 24 while(a!=b){ 25 ans++; 26 if(d[a]>d[b]) a=f[a]; 27 else b=f[b]; 28 } 29 a=c; 30 } 31 printf("%d\n",ans); 32 return 0; 33 }
本来想写树链剖分练练手,结果莫名R,然后顺手写了个LCA(裸的),竟然没T跑的还挺快。
题目来源:CODE[VS]