Codevs 2370 小机房的树
2016-07-09 15:12
387 查看
2370 小机房的树
时间限制: 1 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
传送门
题目描述 Description
小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力
输入描述 Input Description
第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。
第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点
输出描述 Output Description
一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。
样例输入 Sample Input
3
1 0 1
2 0 1
3
1 0
2 0
1 2
样例输出 Sample Output
1
1
2
数据范围及提示 Data Size & Hint
1<=n<=50000, 1<=m<=75000, 0<=c<=1000
分类标签 Tags
最近公共祖先 图论
时间限制: 1 s
空间限制: 256000 KB
题目等级 : 钻石 Diamond
传送门
题目描述 Description
小机房有棵焕狗种的树,树上有N个节点,节点标号为0到N-1,有两只虫子名叫飘狗和大吉狗,分居在两个不同的节点上。有一天,他们想爬到一个节点上去搞基,但是作为两只虫子,他们不想花费太多精力。已知从某个节点爬到其父亲节点要花费 c 的能量(从父亲节点爬到此节点也相同),他们想找出一条花费精力最短的路,以使得搞基的时候精力旺盛,他们找到你要你设计一个程序来找到这条路,要求你告诉他们最少需要花费多少精力
输入描述 Input Description
第一行一个n,接下来n-1行每一行有三个整数u,v, c 。表示节点 u 爬到节点 v 需要花费 c 的精力。
第n+1行有一个整数m表示有m次询问。接下来m行每一行有两个整数 u ,v 表示两只虫子所在的节点
输出描述 Output Description
一共有m行,每一行一个整数,表示对于该次询问所得出的最短距离。
样例输入 Sample Input
3
1 0 1
2 0 1
3
1 0
2 0
1 2
样例输出 Sample Output
1
1
2
数据范围及提示 Data Size & Hint
1<=n<=50000, 1<=m<=75000, 0<=c<=1000
分类标签 Tags
最近公共祖先 图论
/* LCA模板+带权最短路. 处理的时候只需把边权连起来即可. (dis[u]=dis[v]+e[i].next). 然后套LCA模板. fa数组开到D+5即可. */ #include<iostream> #include<cstdio> #include<cstring> #define MAXN 50001 #define MAXM 75001 #define D 21 using namespace std; int n,m,dis[MAXN],tot,fa[MAXN][D+5],head[MAXM],deep[MAXN]; struct data { int x; int v; int next; }e[MAXM<<1]; void add(int u,int v,int x) { e[++tot].v=v; e[tot].x=x; e[tot].next=head[u]; head[u]=tot; } void dfs(int u,int x) { deep[u]=x; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].v; if(!deep[v]&&v) { fa[v][0]=u; dis[v]=dis[u]+e[i].x;//dis处理. dfs(v,x+1); } } } void get_father() { for(int j=1;j<=D;j++) for(int i=0;i<n;i++) { fa[i][j]=fa[fa[i][j-1]][j-1]; } } int get_same(int u,int v) { for(int i=0;i<=D;i++) if((1<<i)&v) u=fa[u][i]; return u; } int lca(int u,int v) { int tot=0; if(deep[u]<deep[v]) swap(u,v); u=get_same(u,deep[u]-deep[v]); for(int i=D;i>=0;i--) { if(fa[u][i]!=fa[v][i]) { u=fa[u][i]; v=fa[v][i]; } } if(u==v) return u; return fa[u][0]; } int main() { int x,y,z; memset(head,-1,sizeof(head)); scanf("%d",&n); for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); add(x,y,z); add(y,x,z); } dfs(0,0); get_father(); dis[0]=0; int u,v; scanf("%d",&m); for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); int ans=lca(u,v); if(ans==u) printf("%d\n",dis[v]-dis[u]); else printf("%d\n",dis[u]+dis[v]-2*dis[ans]); } return 0; }
相关文章推荐
- 使用windows套接字进行网络编程
- Mysql数据库在cmd操作(一)
- Windows 2008 下 P2V windows 2003系统
- SQL SERVER 2008如何建立自动备份的维护计划
- 去除list里面的重复数组的性能比较
- css3-loading效果
- 单调队列: Sliding Window
- 设计模式--策略模式
- LCD 常用的客观效果指标和测试方法
- 【训练题】二分图判定
- UE4中dynamic create component及ChildActorComponent未解析符号 问题
- typescript学习视频
- python 模拟ajax请求
- 杭电1018 BIG NUMBER
- 工具使用-Maven打包问题
- LCD 常用的客观效果指标和测试方法
- 牛人经验3(IC设计行业分类辨析)
- msm8916 lcd 相关调试点指导
- 人才济济的时代诚信才能脱颖而出
- android完美退出自身进程的方法