首页 > 代码库 > hdu--4912--终于解脱了

hdu--4912--终于解脱了

....历经n发wa之后 终于解脱了

这感觉....无法言表...

其实 这题你说难吧? 对于我而言 一共就做过一道lca的人来说 是有点难的

可是吧 当你慢慢地写下来 其实代码那么长 又不怎么难

对于此题 就是先求出query中2个结点的lca之后 然后dfs它们的lca 根据深度进行排序

这个其实不难理解吧? 当然深度越大的 就是离根结点越远 首先进行搜索

然后 就是每搜到一个点 就将它进行标记-已访问过

深搜的时候 注意下 不仅要判断是否访问过 而且要判断这2点的深度关系 肯定是从小的搜到大的

最最注意的就是

depth[v] = depth[u] + 1这句话 不要太随意地写在了lca_tarjan(v)的后面

表示 我就一不留神 写错了 找了好久。。

其余的 就是可以再去好好思索下lca_tarjan的整个算法实现过程

准备 可能 晚上再去学校lca的在线算法...

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

 

today:

  关于思念你的这件小事

  躲得过对酒当歌的夜晚

  躲不过四下无人的街道

 

hdu--4912--终于解脱了