hdu--4547--lca
2014-10-21 13:45
211 查看
这题 一开始想就用并查集来做的 但是有个情况处理不了 2个结点在不同的子树上 这样单纯靠深度就无法正确计算了
那么 就只能用Lca了..
话说 lca 写起来 好长啊 很久不写 -.-
其实 这种算法 每个人都有自己的想法 然后 就会形成自己的关于某个算法的模板 所以 去看别人的代码 会觉得大体上能看懂 一些细节就有点不清楚了
这题 反正 折腾了一晚上啊 我擦叻 -.-
主要在查询的时候 一开始的代码是这样的
就是for i 0 -> m 然后上面这一段代码
这样其实就是埋下了隐患 =-= 其实很容易举出反例
View Code
today:
世人谓我恋何处
其实只恋何处某
那么 就只能用Lca了..
话说 lca 写起来 好长啊 很久不写 -.-
其实 这种算法 每个人都有自己的想法 然后 就会形成自己的关于某个算法的模板 所以 去看别人的代码 会觉得大体上能看懂 一些细节就有点不清楚了
这题 反正 折腾了一晚上啊 我擦叻 -.-
主要在查询的时候 一开始的代码是这样的
addQedge( mp[x] , mp[y] );
就是for i 0 -> m 然后上面这一段代码
这样其实就是埋下了隐患 =-= 其实很容易举出反例
#include <iostream> #include <map> #include <cstring> #include <string> using namespace std; int num1 , num2; const int size1 = 50; const int size2 = 200010; char x[size1] , y[size1]; map<string,int>mp; struct graph { int from; int to; int lca; int next; }; graph node[size2]; int head[size2]; graph Qnode[size2]; int Qhead[size2]; int dist[size2];; int father[size2]; bool vis[size2]; bool flag[size2]; void init( ) { memset( head , -1 , sizeof(head) ); memset( vis , false , sizeof(vis) ); memset( flag , false , sizeof(flag) ); memset( Qhead , -1 , sizeof(Qhead) ); memset( dist , 0 , sizeof(dist) ); } void addEdge( int from , int to ) { node[num1].to = to; node[num1].next = head[from]; head[from] = num1 ++; } void addQedge( int from , int to ) { Qnode[num2].from = from; Qnode[num2].to = to; Qnode[num2].next = Qhead[from]; Qhead[from] = num2 ++; } int find( int x ) { return x == father[x] ? x : father[x] = find( father[x] ); } void lca( int u , int var ) { int v; vis[u] = true; dist[u] = var; father[u] = u; for( int i = head[u] ; ~i ; i = node[i].next ) { v = node[i].to; if( !vis[v] ) { lca( v , 1+var ); father[v] = u; } } for( int i = Qhead[u] ; ~i ; i = Qnode[i].next ) { v = Qnode[i].to; if( vis[v] ) { Qnode[i].lca = Qnode[i^1].lca = find(v); } } } int main() { cin.sync_with_stdio(false); int t , n , m , root , ans , cnt , id; cin >> t; while( t-- ) { cin >> n >> m; init( ); mp.clear(); num1 = num2 = 0; cnt = 1; while( --n ) { cin >> x >> y; if( mp.find(x)==mp.end() ) mp[x] = cnt ++; if( mp.find(y)==mp.end() ) mp[y] = cnt ++; flag[ mp[x] ] = true; addEdge( mp[y] , mp[x] ); } for( int i = 1 ; i<cnt ; i++ ) { if( !flag[i] ) { root = i; break; } } for( int i = 0 ; i<m ; i++ ) { cin >> x >> y; addQedge( mp[x] , mp[y] ); addQedge( mp[y] , mp[x] ); } lca( root , 0 ); for( int i = 0 ; i<m ; i++ ) { id = i*2; if( Qnode[id].from == Qnode[id].to ) cout << 0 << endl; else if( Qnode[id].lca == Qnode[id].from ) cout << 1 << endl; else if( Qnode[id].lca == Qnode[id].to ) cout << dist[ Qnode[id].from ] - dist[ Qnode[id].to ] << endl; else cout << dist[ Qnode[id].from ] - dist[ Qnode[id].lca ] + 1 << endl; } } return 0; }
View Code
today:
世人谓我恋何处
其实只恋何处某
相关文章推荐
- HDU 4547 - CD操作 (LCA)
- HDU 4547 CD操作(LCA)
- Hdu 4547 CD操作 LCA问题
- Hdu 4547 CD操作 LCA问题
- hdu 4547(tarjan LCA)
- HDU 4547 CD操作,lca 求两节点的公共祖先和深度
- HDU 4547 CD操作 LCA
- hdu 4547 lca-tarjan离线算法
- hdu 4547(tarjan LCA)
- HDU-4547-离线LCA
- hdu 4547(tarjan LCA)
- HDU - 4547 倍增法求最近公共祖先(LCA)
- hdu_4547_CD操作(在线LCA)
- hdu 4547 (LCA 倍增法)
- HDU - 4547 - CD操作(LCA)
- hdu_4547_CD操作(在线LCA)
- HDU 4547 CD操作(LCA + BFS)
- hdu 4547(LCA)
- hdu 4547(tarjan LCA)
- hdu 4547 LCA **