zoukankan      html  css  js  c++  java
  • poj1986 (LCA)

    poj1986

    给我们一棵树,求任意两个点之间的距离

    dist[a->b] = dist[a] +dist[b] - 2*lca(a,b)

    要建双向边,数据可能不是严格意义上的树

      1 #include <stdio.h>
      2 #include <string.h>
      3 #include <stdlib.h>
      4 #include <algorithm>
      5 #include <iostream>
      6 #include <queue>
      7 #include <stack>
      8 #include <vector>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <math.h>
     13 using namespace std;
     14 #pragma warning(disable:4996)
     15 typedef long long LL;                   
     16 const int INF = 1<<30;
     17 /*
     18 
     19 */
     20 struct Edge
     21 {
     22     int to,dist;
     23 };
     24 const int MAX_LOG_V = 100;
     25 const int MAX_V = 100000+10;
     26 int parent[MAX_LOG_V][MAX_V];
     27 int depth[MAX_V];
     28 int dist[MAX_V];
     29 vector<Edge> g[MAX_V];
     30 void dfs(int u, int fa, int d)
     31 {
     32     parent[0][u] = fa;
     33     depth[u] = d;
     34     for(int i=0; i<g[u].size(); ++i)
     35         if(g[u][i].to!=fa)
     36         {
     37             dist[g[u][i].to] = dist[u] + g[u][i].dist;
     38             dfs(g[u][i].to,u,d+1);
     39         }    
     40 }
     41 void init(int root, int n)
     42 {
     43     dfs(root,-1,0);
     44     //预处理出parent
     45     for(int k=0; k+1<MAX_LOG_V; ++k)
     46     {
     47         for(int v=1; v<=n; ++v)
     48         {
     49             if(parent[k][v]<0)
     50                 parent[k+1][v] = -1;
     51             else
     52                 parent[k+1][v] = parent[k][parent[k][v]];
     53         }
     54     }
     55 }
     56 int lca(int u, int v)
     57 {
     58     if(depth[u] < depth[v])
     59         swap(u,v);
     60     //让u和v走到同一生度
     61     for(int k=0; k<MAX_LOG_V; ++k)
     62         if((depth[u]-depth[v])>>k&1)//一个数能分解成多个二进制数相加,所以如果&1 为true,那么就向上走
     63             u = parent[k][u];
     64     if(u==v) return u;
     65     //达到同一深度后,二分搜索lca
     66     
     67     for(int k=MAX_LOG_V-1; k>=0; --k)
     68         if(parent[k][v]!=parent[k][u])
     69         {//我们并不知道要向上走多少步,但是只要每次走后,
     70         //parent[k][v]!=parent[k][u],那么这一步就可以向上走,即将要走的步数分解为 1 + 2 + 4 + 8 + ...最后一步将在循环结束后走出
     71             u = parent[k][u];
     72             v = parent[k][v];
     73         }
     74     return parent[0][u];
     75 }
     76 
     77 int main()
     78 {
     79     int n,a,m,i,b,t,root,c;
     80     char str[2];
     81     Edge tmp;
     82     while(scanf("%d%d",&n,&m)!=EOF)
     83     {
     84         
     85         for(i=1; i<=n; ++i)
     86         {
     87             parent[0][i] = -1;
     88             g[i].clear();
     89         }
     90         for(i=0; i<n-1; ++i)
     91         {
     92             scanf("%d%d%d%s",&a,&b,&c,str);
     93             tmp.to = b;
     94             tmp.dist = c;
     95             g[a].push_back(tmp);
     96             tmp.to = a;
     97             g[b].push_back(tmp);
     98         }
     99         root = 1;
    100         dist[root] = 0;
    101         init(root,n);
    102         scanf("%d",&m);
    103         for(i=0; i<m; ++i)
    104         {
    105             scanf("%d%d",&a,&b);
    106             int LCA = lca(a,b);
    107             printf("%d
    ",dist[a]-dist[LCA] + dist[b]-dist[LCA]);
    108         }
    109         
    110         
    111     }
    112     
    113     return 0;
    114 }
  • 相关阅读:
    wxWidgets中wxDateTime与wxString的互操作
    wxWidgets文件操作(六)
    wxWidgets文件操作(三)wxFileDialog与wxTextCtrl
    终于完成词频统计小程序~
    我的第一个c#工程~
    Word frequency program的进展
    List Find和BinarySearch性能比较
    堆和栈
    Java工程师初学Android(四)(转)
    Java中static、this、super、final用法(转http://chytmaths.blog.163.com/blog/static/29482972200610125744333/)
  • 原文地址:https://www.cnblogs.com/justPassBy/p/4515353.html
Copyright © 2011-2022 走看看