zoj 3195 Design the city
来源:互联网 发布:女士牛仔裤品牌 知乎 编辑:程序博客网 时间:2024/05/01 21:57
题意:找无向树上三个点间的距离
题解:在线lca,开始是想分情况讨论,后来发现可以通过求3对两点间距离除以2来求得答案,感觉是一种尝试将问
题规模变小的思想吧。
总结:这个题因为小错改了好久好久才改出来,以后规定自己纯改错时间不得超过20分钟!
下面贴出两种lca转rmq的实现方法
#include<iostream>#include<cstring>#include<cstdio>#include<vector>using namespace std;typedef pair<int,int>pii;#define MAXN 151000#define LOG 20int rmq[MAXN][LOG],s[MAXN],place[MAXN],id[MAXN],deep[MAXN];int cnt,vs;vector<pii>vec[MAXN];void dfs(int u,int fa,int val){ for(int i = 0;i < vec[u].size();i++) { int v = vec[u][i].first,w = vec[u][i].second; if(v == fa)continue; s[v] = val + w; id[++cnt] = v; rmq[++vs][0] = cnt; place[v] = vs; dfs(v,u,val + w); rmq[++vs][0] = rmq[place[u]][0]; }}void init_rmq(){ for(int j = 1;(1 << j) <= vs + 1;j++) for(int i = 0;i <= vs;i++) rmq[i][j] = min(rmq[i][j - 1],rmq[i + (1 << (j - 1))][j - 1]);}int query(int a,int b){ a = place[a],b = place[b]; if(a > b)swap(a,b); int len = -1; while(b - a + 1 >= (1 << (len + 1))) len++; return id[min(rmq[a][len],rmq[b - (1 << len) + 1][len])];}int main(){ int n,u,v,w,_ = 0,q; while(scanf("%d",&n) != EOF) { if(_++)puts(""); for(int i = 0;i < n;i++)vec[i].clear(); for(int i = 1;i < n;i++) { scanf("%d%d%d",&u,&v,&w); vec[u].push_back(pii(v,w)); vec[v].push_back(pii(u,w)); } cnt = vs = 0; dfs(0,-1,0); init_rmq(); scanf("%d",&q); while(q--) { scanf("%d%d%d",&u,&v,&w); int ans1 = s[u] + s[v] - (s[query(u,v)] << 1); int ans2 = s[u] + s[w] - (s[query(u,w)] << 1); int ans3 = s[v] + s[w] - (s[query(v,w)] << 1); printf("%d\n",(ans1 + ans2 + ans3) >> 1); } }}
#include<iostream>#include<cstring>#include<cstdio>#include<vector>using namespace std;typedef pair<int,int>pii;#define MAXN 151000#define LOG 20int rmq[MAXN][LOG],s[MAXN],place[MAXN],deep[MAXN];int cnt,vs;vector<pii>vec[MAXN];void dfs(int u,int fa,int d,int val){ for(int i = 0;i < vec[u].size();i++) { int v = vec[u][i].first,w = vec[u][i].second; if(v == fa)continue; deep[v] = d; s[v] = val + w; rmq[++vs][0] = v; place[v] = vs; dfs(v,u,d + 1,val + w); rmq[++vs][0] = u; }}void init_rmq(){ for(int j = 1;(1 << j) <= vs + 1;j++) for(int i = 0;i <= vs;i++) { int d1 = deep[rmq[i][j - 1]]; int d2 = deep[rmq[i + (1 << (j - 1))][j - 1]]; if(d1 < d2)rmq[i][j] = rmq[i][j - 1]; else rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1]; }}int query(int a,int b){ a = place[a],b = place[b]; if(a > b)swap(a,b); int len = -1; while(b - a + 1 >= (1 << (len + 1))) len++; int d1 = deep[rmq[a][len]]; int d2 = deep[rmq[b - (1 << len) + 1][len]]; if(d1 < d2)return rmq[a][len]; else return rmq[b - (1 << len) + 1][len];}int main(){ int n,u,v,w,_ = 0,q; while(scanf("%d",&n) != EOF) { if(_++)puts(""); for(int i = 0;i < n;i++)vec[i].clear(); for(int i = 1;i < n;i++) { scanf("%d%d%d",&u,&v,&w); vec[u].push_back(pii(v,w)); vec[v].push_back(pii(u,w)); } cnt = vs = 0; dfs(0,-1,1,0); init_rmq(); scanf("%d",&q); while(q--) { scanf("%d%d%d",&u,&v,&w); int ans1 = s[u] + s[v] - (s[query(u,v)] << 1); int ans2 = s[u] + s[w] - (s[query(u,w)] << 1); int ans3 = s[v] + s[w] - (s[query(v,w)] << 1); printf("%d\n",(ans1 + ans2 + ans3) / 2); } }}
0 0
- Zoj 3195 Design the city
- ZOJ 3195 Design the city
- ZOJ 3195 Design the city
- ZOJ - 3195 Design the city
- zoj 3195 Design the city
- zoj 3195 Design the city
- zoj 3195 Design the city LCA
- zoj 3195 Design the city (LCA)
- Design the city - ZOJ 3195 LCA
- zoj 3195 Design the city(LCA)
- ZOJ 3195 — Design the city
- ZOJ - 3195 Design the city(LCA)
- ZOJ 3195Design the city LCA
- ZOJ 3195 Design the city LCA转RMQ
- ZOJ 3195 Design the city (在线LCA,4级)
- ZOJ Problem Set - 3195 Design the city 【Tarjan离线LCA】
- ZOJ 3195 - Design the city(LCA'离线算法Tarjan)
- ZOJ 3195 Design the city(LCA Tarjan)
- 20150208学习总结
- JFinal开发8个常见问题
- uva 514 - Rails
- Android Wifi模块 ScanResult类源码分析(基于Android 5.0)
- This is my first article in csdn.
- zoj 3195 Design the city
- POJ - 2533 Longest Ordered Subsequence
- Android 自定义控件 轻松实现360软件详情页
- MapReduce练习(二)
- CSV介绍
- Core Animation(二)动画基础部分
- poj 3264 Balanced Lineup简单线段树
- codeforces Rockethon 2015 - A. Game (= =)
- UVA 11255 - Necklace (等价置换)