hdu--4547--lca

这题 一开始想就用并查集来做的  但是有个情况处理不了 2个结点在不同的子树上 这样单纯靠深度就无法正确计算了

那么 就只能用Lca了..

话说 lca 写起来 好长啊 很久不写 -.-

其实 这种算法 每个人都有自己的想法 然后 就会形成自己的关于某个算法的模板 所以 去看别人的代码 会觉得大体上能看懂 一些细节就有点不清楚了

这题 反正 折腾了一晚上啊 我擦叻 -.-

主要在查询的时候  一开始的代码是这样的

1 addQedge( mp[x] , mp[y] );

就是for i 0 -> m 然后上面这一段代码

这样其实就是埋下了隐患 =-= 其实很容易举出反例

 

因为 题目明确告诉了我们 确定了根结点 所以其实 建有向图就足够了

然后 如果我的查询是B->C  又很巧的是 我先访问的是A->B这条边 那么当访问到B点的时候 B就会进行询问操作 可是此时C还没有VIS标记过 就无法处理..到了A->C这条边访问到C的时候 可是C并没有查询操作 然后就这样结束了...

所以 修改起来很简单 逆向查询 再添一段

1             addQedge( mp[x] , mp[y] );
2             addQedge( mp[y] , mp[x] );

 

OK 现在放上完整代码 感觉蛮好理解的自己的 #17 。

  1 #include <iostream>
  2 #include <map>
  3 #include <cstring>
  4 #include <string>
  5 using namespace std;
  6 
  7 int num1 , num2;
  8 const int size1 = 50;
  9 const int size2 = 200010;
 10 char x[size1] , y[size1];
 11 map<string,int>mp;
 12 struct graph
 13 {
 14     int from;
 15     int to;
 16     int lca;
 17     int next;
 18 };
 19 graph node[size2];
 20 int head[size2];
 21 graph Qnode[size2];
 22 int Qhead[size2];
 23 int dist[size2];;
 24 int father[size2];
 25 bool vis[size2];
 26 bool flag[size2];
 27 
 28 void init( )
 29 {
 30     memset( head , -1 , sizeof(head) );
 31     memset( vis , false , sizeof(vis) );
 32     memset( flag , false , sizeof(flag) );
 33     memset( Qhead , -1 , sizeof(Qhead) );
 34     memset( dist , 0 , sizeof(dist) );
 35 }    
 36 
 37 void addEdge( int from , int to )
 38 {
 39     node[num1].to = to;
 40     node[num1].next = head[from];
 41     head[from] = num1 ++;
 42 }
 43 
 44 void addQedge( int from , int to )
 45 {
 46     Qnode[num2].from = from;
 47     Qnode[num2].to = to;
 48     Qnode[num2].next = Qhead[from];
 49     Qhead[from] = num2 ++;
 50 }
 51 
 52 int find( int x )
 53 {
 54     return x == father[x] ? x : father[x] = find( father[x] );
 55 }
 56 
 57 void lca( int u , int var )
 58 {
 59     int v;
 60     vis[u] = true;
 61     dist[u] = var;
 62     father[u] = u;
 63     for( int i = head[u] ; ~i ; i = node[i].next )
 64     {
 65         v = node[i].to;
 66         if( !vis[v] )
 67         {
 68             lca( v , 1+var );
 69             father[v] = u;
 70         }
 71     }
 72     for( int i = Qhead[u] ; ~i ; i = Qnode[i].next )
 73     {
 74         v = Qnode[i].to;
 75         if( vis[v] )
 76         {
 77             Qnode[i].lca = Qnode[i^1].lca = find(v);
 78         }
 79     }
 80 }
 81     
 82 int main()
 83 {
 84     cin.sync_with_stdio(false);
 85     int t , n , m , root , ans , cnt , id;
 86     cin >> t;
 87     while( t-- )
 88     {
 89         cin >> n >> m;
 90         init( );
 91         mp.clear();
 92         num1 = num2 = 0;
 93         cnt = 1;
 94         while( --n )
 95         {
 96             cin >> x >> y;
 97             if( mp.find(x)==mp.end() )
 98                 mp[x] = cnt ++;
 99             if( mp.find(y)==mp.end() )
100                 mp[y] = cnt ++;
101             flag[ mp[x] ] = true;
102             addEdge( mp[y] , mp[x] );
103         }
104         for( int i = 1 ; i<cnt ; i++ )
105         {
106             if( !flag[i] )
107             {
108                 root = i;
109                 break;
110             }
111         }    
112         for( int i = 0 ; i<m ; i++ )
113         {
114             cin >> x >> y;
115             addQedge( mp[x] , mp[y] );
116             addQedge( mp[y] , mp[x] );
117         }
118         lca( root , 0 );
119         for( int i = 0 ; i<m ; i++ )
120         {
121             id = i*2;
122              if( Qnode[id].from == Qnode[id].to )
123                 cout << 0 << endl;
124             else if( Qnode[id].lca == Qnode[id].from )
125                 cout << 1 << endl;
126             else if( Qnode[id].lca == Qnode[id].to )
127                 cout << dist[ Qnode[id].from ] - dist[ Qnode[id].to ] << endl;
128             else 
129                 cout << dist[ Qnode[id].from ] - dist[ Qnode[id].lca ] + 1 << endl;
130         }
131     }
132     return 0;
133 }
View Code

 

today:

  世人谓我恋何处

  其实只恋何处某

 

posted @ 2014-10-21 13:45  radical  阅读(132)  评论(0编辑  收藏  举报