码迷,mamicode.com
首页 > 其他好文 > 详细

在线二分求LCA

时间:2014-11-01 09:45:47      阅读:297      评论:0      收藏:0      [点我收藏+]

标签:style   blog   io   color   os   ar   for   sp   div   

#include<iostream>
#include<cstring>
#include<set>
#include<map>
#include<cmath>
#include<stack>
#include<queue>
#include<deque>
#include<list>
#include<algorithm>
#include<stdio.h>
#include<iomanip>

#define rep(i,n) for(int i=0;i<n;++i)
#define fab(i,a,b) for(int i=a;i<=b;++i)
#define fba(i,b,a) for(int i=b;i>=a;--i)
#define PB push_back
#define INF 0x3f3f3f3f
#define MP make_pair
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define sf scanf
#define pf printf
#define LL long long
const int N=100010;
const int maxn=N;
const int logmaxn=20;
using namespace std;
typedef pair<int,int>PII;
/*
struct LCA {
  int n;
  int fa[maxn];   // 父亲数组
  int cost[maxn]; // 和父亲的费用
  int L[maxn];    // 层次(根节点层次为0)
  int anc[maxn][logmaxn];     // anc[p][i]是结点p的第2^i级父亲。anc[i][0] = fa[i]
  int maxcost[maxn][logmaxn]; // maxcost[p][i]是i和anc[p][i]的路径上的最大费用

  // 预处理,根据fa和cost数组求出anc和maxcost数组
  void preprocess() {
    for(int i = 0; i < n; i++) {
      anc[i][0] = fa[i]; maxcost[i][0] = cost[i];
      for(int j = 1; (1 << j) < n; j++) anc[i][j] = -1;
    }   
    for(int j = 1; (1 << j) < n; j++)
      for(int i = 0; i < n; i++)
        if(anc[i][j-1] != -1) {
          int a = anc[i][j-1];
          anc[i][j] = anc[a][j-1];
          maxcost[i][j] = max(maxcost[i][j-1], maxcost[a][j-1]);
        }
  }

  // 求p到q的路径上的最大权
  int query(int p, int q) {
    int tmp, log, i;
    if(L[p] < L[q]) swap(p, q);
    for(log = 1; (1 << log) <= L[p]; log++); log--;

    int ans = -INF;
    for(int i = log; i >= 0; i--)
      if (L[p] - (1 << i) >= L[q]) { ans = max(ans, maxcost[p][i]); p = anc[p][i];}
   
    if (p == q) return ans; // LCA为p
   
    for(int i = log; i >= 0; i--)
      if(anc[p][i] != -1 && anc[p][i] != anc[q][i]) {
        ans = max(ans, maxcost[p][i]); p = anc[p][i];
        ans = max(ans, maxcost[q][i]); q = anc[q][i];
      }

    ans = max(ans, cost[p]);
    ans = max(ans, cost[q]);
    return ans; // LCA为fa[p](它也等于fa[q])
  }  
};
*/
struct LCA{
   int n,fa[N],cost[N],L[N],anc[N][20],maxcost[N][20];
   void preprocess(){
       rep(i,n){
           anc[i][0]=fa[i];maxcost[i][0]=cost[i];
           for(int j=1;(1<<j)<n;j++){
               anc[i][j]=-1;
           }
       }
       for(int j=1;(1<<j)<n;j++){
           rep(i,n){
               if(anc[i][j-1]!=-1){
                   int p=anc[i][j-1];
                   anc[i][j]=anc[p][j-1];
                   maxcost[i][j]=max(maxcost[i][j-1],maxcost[p][j-1]);
               }
           }
       }
   }
   int query(int p,int q){
        int k=0;
        if(L[p]<L[q])swap(p,q);
        while((1<<(k+1))<=L[p])k++;
   //     for(k=1;(1<<k)<=L[p];k++);k--;
        int ans=-INF;
        fba(i,k,0)if(L[p]-(1<<i)>=L[q]){
            ans=max(ans,maxcost[p][i]);
            p=anc[p][i];
        }
        if(p==q)return ans;/// lca = p 
        fba(i,k,0)if(anc[p][i]!=-1&&anc[p][i]!=anc[q][i]){
            ans=max(ans,maxcost[p][i]);p=anc[p][i];
            ans=max(ans,maxcost[q][i]);q=anc[q][i];
        }
        ans=max(ans,cost[p]);
        ans=max(ans,cost[q]);
        return ans;// lca = fa[p] = fa[q];
   }
};
LCA solver;

int pa[N];
int find(int x){
    return x==pa[x]?x:pa[x]=find(pa[x]);
}
vector<PII>G[N];
void dfs(int u,int fa,int lev){
    solver.L[u]=lev;
    rep(i,G[u].size()){
        int v=G[u][i].first;
        if(v!=fa){
            solver.fa[v]=u;
            solver.cost[v]=G[u][i].second;
            dfs(v,u,lev+1);
        }
    }
}
struct Edge{
    int u,v,d;
    bool operator< (const Edge& rhs)const{
        return d < rhs.d;
    }
}E[N];
int main(){
    int cas=0,n,m,Q;
    while(~sf("%d%d",&n,&m)&&n){
        rep(i,m){
            sf("%d%d%d",&E[i].u,&E[i].v,&E[i].d);
            E[i].u--;E[i].v--;
        }
        sort(E,E+m);
        rep(i,n){pa[i]=i;G[i].clear();}
        rep(i,m){
            int x=E[i].u,y=E[i].v,u=find(x),v=find(y);
            if(u!=v){
                pa[u]=v;
                G[x].PB(MP(y,E[i].d));
                G[y].PB(MP(x,E[i].d));
            }
        }
        solver.n=n;
        dfs(0,-1,0);
        solver.preprocess();
        if(++cas!=1)pf("\n");
        sf("%d",&Q);
        while(Q--){
            int a,b;sf("%d%d",&a,&b);
            pf("%d\n",solver.query(a-1,b-1));
        }
    }
    return 0;
}

 

在线二分求LCA

标签:style   blog   io   color   os   ar   for   sp   div   

原文地址:http://www.cnblogs.com/wanggp3/p/4066416.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!