BZOJ 1602: [Usaco2008 Oct]牧场行走
题目
1602: [Usaco2008 Oct]牧场行走
Time Limit: 5 Sec Memory Limit: 64 MBDescription
N头牛(2<=n<=1000)别人被标记为1到n,在同样被标记1到n的n块土地上吃草,第i头牛在第i块牧场吃草。 这n块土地被n-1条边连接。 奶牛可以在边上行走,第i条边连接第Ai,Bi块牧场,第i条边的长度是Li(1<=Li<=10000)。 这些边被安排成任意两头奶牛都可以通过这些边到达的情况,所以说这是一棵树。 这些奶牛是非常喜欢交际的,经常会去互相访问,他们想让你去帮助他们计算Q(1<=q<=1000)对奶牛之间的距离。
Input
*第一行:两个被空格隔开的整数:N和Q
*第二行到第n行:第i+1行有两个被空格隔开的整数:AI,BI,LI
*第n+1行到n+Q行:每一行有两个空格隔开的整数:P1,P2,表示两头奶牛的编号。
Output
*第1行到第Q行:每行输出一个数,表示那两头奶牛之间的距离。
Sample Input
4 2
2 1 2
4 3 2
1 4 3
1 2
3 2
2 1 2
4 3 2
1 4 3
1 2
3 2
Sample Output
2
7
7
题解
这题就是一个裸的LCA,值得高兴的是我竟然是写了一遍之后调都没调直接交就A掉了,好开心~
代码
/*Author:WNJXYK*/ #include<cstdio> #include<iostream> #include<cstring> #include<string> #include<algorithm> #include<queue> #include<set> #include<map> using namespace std; #define LL long long inline void swap(int &x,int &y){int tmp=x;x=y;y=tmp;} inline void swap(LL &x,LL &y){LL tmp=x;x=y;y=tmp;} inline int remin(int a,int b){if (a<b) return a;return b;} inline int remax(int a,int b){if (a>b) return a;return b;} inline LL remin(LL a,LL b){if (a<b) return a;return b;} inline LL remax(LL a,LL b){if (a>b) return a;return b;} int ans[1005][20]; int dep[1005]; struct Edge{ int u,v; int l; int nxt; Edge(){} Edge(int a,int b,int c,int d){u=a;v=b;l=c;nxt=d;} }; Edge e[5005]; int head[1005]; int nume=0; bool visited[1005]; int dist[1005]; inline void addEdge(int x,int y,int c){ e[++nume]=Edge(x,y,c,head[x]); head[x]=nume; e[++nume]=Edge(y,x,c,head[y]); head[y]=nume; } void dfs(int x,int depth,int dists){ visited[x]=true; dep[x]=depth; dist[x]=dists; for (int i=1;i<=10;i++){ ans[x][i]=ans[ans[x][i-1]][i-1]; } for (int i=head[x];i;i=e[i].nxt){ int g=e[i].v; if (visited[g]==false){ ans[g][0]=x; dfs(g,depth+1,dists+e[i].l); } } } inline void swim(int &x,int h){ for (int i=0;h;i++){ if (h&1) x=ans[x][i]; h/=2; } } inline int lca(int x,int y){ if (dep[x]<dep[y])swap(x,y); swim(x,dep[y]-dep[x]); if (x==y) return x; for (;;){ int index=0; for (;ans[x][index]!=ans[y][index];index++); if (index==0) return ans[x][0]; x=ans[x][index-1]; y=ans[y][index-1]; } } int n,Q; int main(){ scanf("%d%d",&n,&Q); for (int i=1;i<=n-1;i++){ int x,y,c; scanf("%d%d%d",&x,&y,&c); addEdge(x,y,c); } ans[1][0]=1; dfs(1,1,0); for (int i=1;i<=Q;i++){ int x,y; scanf("%d%d",&x,&y); int lc=lca(x,y); printf("%d\n",dist[x]+dist[y]-dist[lc]*2); } return 0; }