bzoj 1602 [Usaco2008 Oct]牧场行走(LCA模板)
2016-01-03 14:54
363 查看
1602: [Usaco2008 Oct]牧场行走
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 379 Solved: 216
[Submit][Status][Discuss]
Description
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 22 1 2
4 3 2
1 4 3
1 2
3 2
Sample Output
27
HINT
Source
资格赛【代码】
//O(qlogn)
#include<cstdio> #include<cstring> #include<queue> #include<vector> #include<iostream> using namespace std; const int maxn = 100000+10; const int maxq = 100000+10; struct Edge{ int u,v,w; }; struct node { int v,i; }; vector<int> G[maxn]; vector<Edge> es; vector<node> que[maxn]; int U[maxq],V[maxq]; void addedge(int u,int v,int w) { es.push_back((Edge){u,v,w}); int m=es.size(); G[u].push_back(m-1); } int p[maxn]; int find(int u) { return u==p[u]? u:p[u]=find(p[u]); } int dist[maxn]; void dfs(int u,int fa) { //求dist for(int i=0;i<G[u].size();i++) { Edge e=es[G[u][i]]; int v=e.v; if(v!=fa) dist[v]=dist[u]+e.w , dfs(v,u); } } int vis[maxn],lca[maxq]; void tarjan(int u,int fa) { p[u]=u; for(int i=0;i<G[u].size();i++) { Edge e=es[G[u][i]]; int v=e.v; if(v!=fa) tarjan(v,u),p[v]=u; //递归处理 合并集合 } vis[u]=1; for(int i=0;i<que[u].size();i++) { //求与u相关的询问 int v=que[u][i].v; if(vis[v]) lca[que[u][i].i]=find(v); //如果已经被访问 lca为v集合的代表元x //若v是u子则x=u 若非子则因u还未访问完集合并未向上合并所以代表元为lca } } int n,q; void read(int& x) { char c=getchar(); while(!isdigit(c)) c=getchar(); x=0; while(isdigit(c)) x=x*10+c-'0' , c=getchar(); } int main() { read(n),read(q); int u,v,w; for(int i=1;i<n;i++) { read(u),read(v),read(w); addedge(u,v,w) , addedge(v,u,w); } for(int i=0;i<q;i++) { read(u),read(v); U[i]=u , V[i]=v; que[u].push_back((node){v,i}); que[v].push_back((node){u,i}); } tarjan(n>>1,-1) , dfs(n>>1,-1); for(int i=0;i<q;i++) { u=U[i] , v=V[i]; int lc=lca[i]; printf("%d\n",dist[u]+dist[v]-(dist[lc]<<1)); } return 0; }
tarjan
LCA的一种比较快的写法
//////////////////////////////////////////////////// int siz ,top ,son ,fa ; void dfs1(int u) { siz[u]=1,son[0]=0; dfn[u]=++dfsc; for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(v!=fa[u]) { fa[v]=u; d[v]=d[u]+1; dfs1(v); siz[u]+=siz[v]; if(siz[v]>siz[son[u]]) son[u]=v; } } } void dfs2(int u,int tp) { top[u]=tp; if(son[u]) dfs2(son[u],tp); for(int i=0;i<g[u].size();i++) { int v=g[u][i]; if(v!=son[u] && v!=fa[u]) dfs2(v,v); } } int LCA(int u,int v) { while(top[u]!=top[v]) if(d[top[u]]>=d[top[v]]) u=fa[top[u]]; else v=fa[top[v]]; return d[u]<d[v]? u:v; } ////////////////////////////////////////////////
题目部分戳这:/article/6765642.html
相关文章推荐
- letcode之Recover Binary Search Tree
- 顺序表一系列操作
- mokoid android open source HAL hacking in a picture
- [codeforces]Goodbye_2015
- .NET中类型转换的一些等价用法
- 精神粮食--有梦想的人可以看看
- MVC导出Excle
- 一个可以用于在百科搜索大量关键词的python爬虫
- HDU 2602 Bone Collector(01背包)
- mysql 导入&导出sql文件
- 一致性Hash算法
- 云计算架构
- POJ2570 Fiber Network(Floyd)
- Swift开发IOS-UITextField
- 我们要科学不要激情
- 2016-2019三年计划
- 【费用流】hdu1533 poj2516 bzoj1070 bzoj1061
- 重拾博客
- ubuntu 14.04 安装openssh-server报错问题解决
- 【数学模型】椅子能在不平的地面上放平吗?(1)