oj_468 出去玩
来源:互联网 发布:数据有效性快捷方式 编辑:程序博客网 时间:2024/05/17 01:50
题目描述
Problem 468: 出去玩
Time Limit: 1000 ms
Memory Limit: 262144 KB
Problem Description
穷游中国队又去游中国了。
穷游中国队去到了一个城市,这个城市有n个区,n-1条路,每条路连接不同的两个区,而且每两个区有且仅有一条路径,每条路上都有一个收费站,如果经过这条路就要收取一定的费用。
现在穷游中国队在编号为a的区住了一个晚上,第二天打算去编号为b的区,问路费一共要花多少钱?(在一个区里面行走不用收费)
Input
第一行两个数n和q,表示区的个数和询问个数
接下来有n-1行,每行三个数i,j,k,表示第i个区到第j个区有一条路,且要收费k元
接下来有q行,每行两个数,分别是a和b
【数据约定】
30%的数据 2<=n<=400
100%的数据 2<=n<=40000 1<=m<=200 0
题解
画了几个图发现是最近公共祖先(lca)的题
lca有很多种做法
1)暴力(带深度dfs)
最坏:O(n*m)(退化成一条链)数据水可以ac
一步一步往上跳(找父亲)
#include<cstdio>#include<iostream>#define N 40010using namespace std;int n,m,num,d[N],f[N],h[N],p,q,o,a[N];struct edge{ int p,q,o,n;}b[2*N];void ljb(int p,int q,int o){ b[++num].n=h[p]; h[p]=num; b[num].p=p; b[num].q=q; b[num].o=o;}void dfs(int x,int de){ d[x]=de; int j=h[x]; while(j!=0){ if(d[b[j].q]==0){ f[b[j].q]=x; a[b[j].q]=b[j].o; dfs(b[j].q,de+1); } j=b[j].n; }}int lca(int p,int q){ int ans=0; if(d[p]>d[q])swap(p,q); while(d[p]<d[q]){ ans+=a[q]; q=f[q]; } while(p!=q){ ans+=a[p]; p=f[p]; ans+=a[q]; q=f[q]; } return ans;}int main(){ freopen("data.txt","r",stdin); scanf("%d%d",&n,&m); for(int i=1;i<n;i++){ scanf("%d%d%d",&p,&q,&o); ljb(p,q,o); ljb(q,p,o); } dfs(1,1);// for(int i=1;i<=n;i++)printf("%d ",f[i]); for(int i=1;i<=m;i++){ scanf("%d%d",&p,&q); printf("%d\n",lca(p,q)); }}
2)
倍增,f【j】【i】表示j的第2^i的祖先,f【j】【0】表示j的父亲
最坏:O(log(n)*m)(退化成一条链)
f[j][i]=f[f[j][i-1]][i-1];
其他和暴力一样
#include<cstdio>#include<iostream>#include<cmath>#define N 40010using namespace std;int f[N][20],n,m,num,nu,h[N],a[N],d[N],p,q,o;struct edge{ int p,q,o,n;}b[2*N];void ljb(int p,int q,int o){ b[++num].n=h[p]; h[p]=num; b[num].p=p; b[num].q=q; b[num].o=o;}void dfs(int x,int de){ d[x]=de; int j=h[x]; while(j!=0){ if(d[b[j].q]==0){ a[b[j].q]=a[x]+b[j].o; f[b[j].q][0]=x; dfs(b[j].q,de+1); } j=b[j].n; }}void fa(){//求祖先 for(int i=1;i<=nu;i++){ for(int j=1;j<=n;j++){ f[j][i]=f[f[j][i-1]][i-1]; } }}int lca(int p,int q){//处理询问 int ans=a[p]+a[q]; if(d[p]>d[q])swap(p,q); int w=d[q]-d[p],j=1; for(int i=0;j<=w;i++){ if(j&w)q=f[q][i]; j*=2; } if(p!=q){ for(int i=nu;i>=0;i--){ if(f[p][i]!=f[q][i]){ p=f[p][i]; q=f[q][i]; } if(f[p][0]==f[q][0])break; } p=f[p][0]; } ans-=a[p]*2; return ans;}int main(){ freopen("data.txt","r",stdin); scanf("%d%d",&n,&m); nu=log(n)/log(2); for(int i=1;i<n;i++){ scanf("%d%d%d",&p,&q,&o); ljb(p,q,o); ljb(q,p,o); } dfs(1,1); fa();// for(int i=1;i<=n;i++)printf("%d ",a[i]);// printf("\n"); for(int i=1;i<=m;i++){ scanf("%d%d",&p,&q); printf("%d\n",lca(p,q)); }}
3)dfs序
4)tarjan(离线)O(1)
5)树链剖分
0 0
- oj_468 出去玩
- 出去玩了
- Candy 出去玩
- 姐姐,我要出去玩~
- 今天要出去玩了
- Candy 出去玩 (outing)
- GFOJ Problem 468: 出去玩 LCA
- GFOJ problem468 出去玩 解题报告
- 难得出去玩啊!拍了好多相片
- 贴几首当年端午节和女朋友一起出去玩的小诗!!
- 丰富码农的不加班生活,带码农出去玩
- 海南风光; 5/1没有出去玩的朋友,进来看看吧............
- 公交夫妻上对班每日梦中相见 最渴望假期带娃出去玩
- 没钱、没时间怎么出去玩?——那就带上自由与尊重去旅行
- 今天晚上玩累了,不写程序了,过会早点睡,难得出去走走也不错
- 出去打牌
- 今天出去。
- 出去吃饭
- 设计模式–单例模式
- LightOJ1370Bi-shoe and Phi-shoe(欧拉函数)
- 文章标题
- redis简介
- 函数模板和普通函数的抉择
- oj_468 出去玩
- php配置
- 模板&泛型编程
- mybatis进行测试时找不到配置文件:java.io.IOException: Could not find resource config/SqlMapConfig.xml 的解决
- map 用法
- html前端如何将一个页面表单内的数据全部传递到另一个页面?
- 学习JavaScript设计模式(五)
- NYOJ32 组合数(深搜DFS)
- 《ACM程序设计》书中题目―Y