zoukankan      html  css  js  c++  java
  • HDU4547+LCA

    有向边!!!

      1 #include<stdio.h>
      2 #include<string>
      3 #include<map>
      4 #include<stdlib.h>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<math.h>
      8 using namespace std;
      9 const int maxn = 200005;
     10 struct node{
     11     int from,to,next,val;
     12 }edge[ maxn<<2 ];
     13 int cnt,head[ maxn ];
     14 map<string,int>mp;
     15 
     16 void addedge( int a,int b,int c ){
     17     edge[ cnt ].from = a;
     18     edge[ cnt ].to = b;
     19     edge[ cnt ].next = head[ a ];
     20     head[ a ] = cnt++;
     21 }
     22 int ace[ maxn ];//最近公共祖先
     23 int deep[ maxn ];
     24 int fa[ maxn ];
     25 int dis[ maxn ];
     26 
     27 void init(){
     28     cnt = 0;
     29     mp.clear();
     30     memset( fa,0,sizeof(fa) );
     31     memset( head,-1,sizeof( head ) );
     32 }
     33 
     34 void dfs( int now,int now_father,int now_ace,int now_deep,int now_dis ){
     35     fa[ now ]=now_father;
     36     deep[ now ]=now_deep;
     37     dis[ now ]=now_dis;
     38     ace[ now ]=now_ace;
     39     for( int i=head[ now ];i!=-1;i=edge[ i ].next ){
     40         int v=edge[ i ].to;
     41        // if( fa[ v ]==0 )
     42             dfs( v,now,now_ace,now_deep+1,now_dis+edge[ i ].val );
     43     }
     44 }
     45 
     46 int find( int x,int y ){
     47     if( x==y ) return x;
     48     if( deep[ x ]>deep[ y ] ){
     49         return find( fa[x],y );
     50     }
     51     else{
     52         return find( x,fa[y] );
     53     }
     54 }
     55 
     56 int main(){
     57     int ca;
     58     scanf("%d",&ca);
     59     while( ca-- ){
     60         int n,m;
     61         scanf("%d%d",&n,&m);
     62         init();
     63         string a,b;
     64         int num1,num2;
     65         int cc = 1;
     66         for( int i=0;i<n-1;i++ ){
     67             cin>>a>>b;
     68             if( mp[a]==0 ){
     69                 mp[a] = cc;
     70                 num1 = cc;
     71                 cc++;
     72             }
     73             else num1 = mp[a];
     74             if( mp[b]==0 ){
     75                 mp[b] = cc;
     76                 num2 = cc;
     77                 cc++;
     78             }
     79             else num2 = mp[b];
     80             addedge( num2,num1,1 );
     81             //addedge( num1,num2,1 );
     82             //cout<<a<<"="<<num1<<" ";
     83             //cout<<b<<"="<<num2<<endl;
     84         }
     85         for( int i=1;i<cc;i++ ){
     86             if( fa[i]==0 ){    
     87                 dfs( i,-1,i,0,1 );
     88             }
     89         }
     90         /*
     91         for( int i=1;i<cc;i++ ){
     92             printf("now = %d\n",i);
     93             printf("dis[%d]=%d ace[%d]=%d fa[%d]=%d deep[%d]=%d\n\n",i,dis[i],i,ace[i],i,fa[i],i,deep[i]);
     94         }
     95         */
     96         while( m-- ){
     97             cin>>a>>b;
     98             num1 = mp[a];
     99             num2 = mp[b];
    100             int father = find( num1,num2 );
    101             if( father==num2 ){
    102                 printf("%d\n",abs(deep[num2]-deep[num1]));
    103             }
    104             else if( father==num1 ){
    105                 printf("1\n");
    106             }
    107             else{
    108                 printf("%d\n",abs(deep[num1]-deep[father])+1);
    109             }
    110 
    111         }
    112     }
    113     return 0;
    114 }
    View Code

    再贴一个tarjan版本的。。。

      1 /*
      2 lca+tarjan
      3 */
      4 #include<stdio.h>
      5 #include<string.h>
      6 #include<stdlib.h>
      7 #include<algorithm>
      8 #include<iostream>
      9 #include<queue>
     10 #include<map>
     11 #include<math.h>
     12 using namespace std;
     13 typedef long long ll;
     14 //typedef __int64 int64;
     15 const int maxn = 100105;
     16 const int inf = 0x7fffffff;
     17 const double pi=acos(-1.0);
     18 const double eps = 1e-8;
     19 
     20 int fa[ maxn ],ace[ maxn ],dis[ maxn ],vis[ maxn ];
     21 struct node{
     22     int u,next;
     23 }edge[ maxn<<4 ],ex_edge[ maxn<<4 ];
     24 struct  node2{
     25     int u,next,val;
     26 }ans_edge[ maxn ];
     27 struct  node3{
     28     int u,v,fa;
     29 }query[ maxn ];
     30 int cnt,head[ maxn ],ex_cnt,ex_head[ maxn ],ans_cnt,ans_head[ maxn ];
     31 map<string,int>mp;
     32 
     33 void init(){
     34     cnt = ex_cnt = ans_cnt = 0;
     35     mp.clear();
     36     memset( ans_head,-1,sizeof( ans_head ) );
     37     memset( ex_head,-1,sizeof( ex_head ) );
     38     memset( head,-1,sizeof( head ) );
     39 }
     40 void addedge( int a,int b ){
     41     edge[ cnt ].u = b;
     42     edge[ cnt ].next = head[ a ];
     43     head[ a ] = cnt++;
     44 }
     45 void ex_addedge( int a,int b ){
     46     ex_edge[ ex_cnt ].u = b;
     47     ex_edge[ ex_cnt ].next = ex_head[ a ];
     48     ex_head[ a ] = ex_cnt++;
     49 }
     50 void ans_addedge( int a,int b,int c ){
     51     ans_edge[ ans_cnt ].u = b;
     52     ans_edge[ ans_cnt ].val = c;
     53     ans_edge[ ans_cnt ].next = ans_head[ a ];
     54     ans_head[ a ] = ans_cnt++;
     55 }
     56 void make_set( int x ){
     57     fa[x] = x;
     58 }
     59 
     60 int file_root;
     61 void dfs( int cur ){
     62     if( vis[ cur ]==1 ) return ;
     63     vis[ cur ] = 1;
     64     file_root = cur;
     65     for( int i=ex_head[ cur ];i!=-1;i=ex_edge[ i ].next ){
     66         if( vis[ ex_edge[ i ].u ]==0 ){
     67             dfs( ex_edge[ i ].u );
     68         }
     69     }
     70 }//寻找根目录
     71 
     72 int find( int x ){
     73     if( fa[x]==x ) return x;
     74     return fa[x] = find( fa[x] );
     75 }
     76 
     77 void tarjan_of_lca( int cur,int dist ){
     78     make_set( cur );
     79     vis[ cur ] = 1;
     80     dis[ cur ] = dist;
     81     for( int i=head[ cur ];i!=-1;i=edge[ i ].next ){
     82         if( vis[ edge[ i ].u ]==0 ){
     83             tarjan_of_lca( edge[ i ].u,dist+1 );
     84             fa[ edge[ i ].u ] = cur;
     85         }
     86     }
     87     for( int i=ans_head[ cur ];i!=-1;i=ans_edge[ i ].next ){
     88         if( vis[ ans_edge[ i ].u ]==1 ){
     89             int father = find( ans_edge[ i ].u );
     90             query[ ans_edge[ i ].val ].fa = father;
     91             //printf("cur=%d,nxt=%d,father=%d\n",cur,ans_edge[ i ].u,father);
     92             //printf("dis_cur=%d,dis_nxt=%d,dis_fa=%d\n\n",dis[cur],dis[ans_edge[ i ].u],dis[father]);
     93         }
     94     }//在这里寻找公共祖先,至于原因与dfs的过程有关
     95 } 
     96 
     97 int main(){
     98     int ca;
     99     scanf("%d",&ca);
    100     while( ca-- ){
    101         int n,m;
    102         scanf("%d%d",&n,&m);
    103         init();
    104         string a,b;
    105         int f1,f2;
    106         int cc = 1;
    107         n--;
    108         while( n-- ){
    109             cin>>a>>b;
    110             if( mp[a]==0 ) mp[a] = cc++;
    111             if( mp[b]==0 ) mp[b] = cc++;
    112             f1 = mp[a];
    113             f2 = mp[b];
    114             addedge( f2,f1 );
    115             ex_addedge( f1,f2 );
    116         }
    117         file_root  = -1;
    118         memset( vis,0,sizeof( vis ) );
    119         dfs( f1 );//find the root
    120         for( int i=1;i<=m;i++ ){
    121             cin>>a>>b;
    122             f1 = mp[a];
    123             f2 = mp[b];
    124             ans_addedge( f1,f2,i );
    125             ans_addedge( f2,f1,i );//存边 便于在tarjan的过程中存下最近公共祖先
    126             query[ i ].u = f1;
    127             query[ i ].v = f2;//query记录询问的节点
    128         }
    129         memset( vis,0,sizeof( vis ) );
    130         tarjan_of_lca( file_root,0 );
    131         for( int i=1;i<=m;i++ ){
    132             if( query[ i ].u==query[ i ].v ) printf("0\n");
    133             else if( query[ i ].fa==query[ i ].u ) printf("1\n");
    134             else if( query[ i ].fa==query[ i ].v ) printf("%d\n",abs( dis[ query[ i ].u ]-dis[ query[ i ].v ]));
    135             else {
    136                 printf("%d\n",dis[query[ i ].u]-dis[ query[ i ].fa ]+1);
    137             }
    138             //printf("%d\n",ans[i]);
    139         }
    140     }
    141     return 0;
    142 }
    View Code

    lca的tarjan版本过程很重要,在dfs过程中,当遇到询问的一对点时候,就要求出结果ace

  • 相关阅读:
    express基础介绍
    gruntjs
    小写转换大写(人民币)
    Elasticsearch学习系列之多文档操作mget
    java.util.Date和java.sql.Date的使用方法,转载
    spring学习IOC
    oracle10g手动创建scott(tiger)的方法(转)
    观察者模式
    简单工厂,工厂模式,抽象工厂
    win7主机+winxp虚拟机,虚拟机使用主机的无线网卡(转)
  • 原文地址:https://www.cnblogs.com/xxx0624/p/3093294.html
Copyright © 2011-2022 走看看