zoukankan      html  css  js  c++  java
  • 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:

      世人谓我恋何处

      其实只恋何处某

    just follow your heart
  • 相关阅读:
    多线程编程(2):线程的同步
    C#中listview实现排序
    [PLC]S7-300的数据类型
    C# 多线程编程(4):多线程与UI操作
    Thunderbird 80 column FIX 发出的邮件也需要在80列处line break
    vsftp 500 OOPS: vsftpd: refusing to run with writable anonymous root
    科普 What is YUV
    转载:网站真的可以无密码登录么?
    Ubuntu 12.04安装Microsoft lifecam studio摄像头
    Thunderbird on Ubuntu 12.04 调整邮件列表行间距
  • 原文地址:https://www.cnblogs.com/radical/p/4040187.html
Copyright © 2011-2022 走看看