• LCA(最近公共祖先)模板


      Tarjan版本

    /*  gyt
           Live up to every day            */
    #pragma comment(linker,"/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 1e5+5;
    const ll maxm = 1e7;
    const ll base = 2333;
    const int INF = 1<<30;
    const db eps = 1e-8;
    const ll mod = 1e9+7;
    struct Edge{
        int u, v, next, val;
    }edge[maxn*2], edge1[maxn*2];
    int n, m;
    int head[maxn], head1[maxn];
    int father[maxn], dis[maxn], tol, toll, LCA[maxn];
    bool visit[maxn];
    int cnt;
    //LCA[]最近公共祖先
    
    void init() {
        cnt=0;
        memset(head, -1, sizeof(head));
        memset(head1, -1, sizeof(head1));
        tol=toll=0;
        memset(visit, 0, sizeof(visit));
        memset(LCA, 0, sizeof(LCA));
        memset(dis, 0, sizeof(dis));
    }
    void add(int u, int v, int w) {
        edge[tol].u=u, edge[tol].v=v,edge[tol].val=w;
        edge[tol].next=head[u];
        head[u]=tol++;
    }
    void add1(int u, int v, int w) {
        edge1[toll].u=u, edge1[toll].v=v,edge1[toll].val=w;
        edge1[toll].next=head1[u];
        head1[u]=toll++;
    }
    int Find(int x) {
        if (x!=father[x])  father[x]=Find(father[x]);
        return father[x];
    }
    void tarjan(int u) {
        visit[u]=1;
        father[u]=u;
        for (int j=head1[u]; ~j; j=edge1[j].next) {
            int v=edge1[j].v;
            if (visit[v])  LCA[edge1[j].val]=Find(v);
        }
        for (int j=head[u]; ~j; j=edge[j].next) {
            int v=edge[j].v;
            if (!visit[v]) {
                dis[v]=dis[u]+edge[j].val;
                tarjan(v);
                father[v]=u;
                //cout<<dis[v]<<endl;
            }
        }
    }
    void solve() {
        init();
        scanf("%d%d", &n, &m);
        for (int i=1; i<n; i++) {
            int a, b, c;  scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);  add(b, a, c);
        }
        for (int i=0; i<m; i++) {
            int a, b;  scanf("%d%d", &a, &b);
            add1(a, b, i);  add1(b, a, i);
        }
        dis[1]=0;
        tarjan(1);
        for(int i=0;i<toll;i+=2){
            printf("%d
    ",LCA[edge1[i].val]);
        }
    }
    int main() {
        int t = 1;
        //freopen("in.txt","r",stdin);
      //  freopen("gcd.out","w",stdout);
         scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }

       倍增版本

    /*  gyt
           Live up to every day            */
    #pragma comment(linker,"/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #include<stack>
    #include<cstring>
    #include<queue>
    #include<set>
    #include<string>
    #include<map>
    #include <time.h>
    #define PI acos(-1)
    using namespace std;
    typedef long long ll;
    typedef double db;
    const int maxn = 1e5+5;
    const ll maxm = 1e7;
    const ll base = 2333;
    const int INF = 1<<30;
    const db eps = 1e-8;
    const ll mod = 1e9+7;
    struct Edge{
        int u, v, next, val;
    }edge[maxn*2];
    int head[maxn], dis[maxn];
    int f[maxn], deep[maxn], p[maxn][20];
    int n, m, cnt;
    
    void init() {
        int i,j;
        for(j=0;(1<<j)<=n;j++)
            for(i=1;i<=n;i++)
            p[i][j]=-1;
        for(i=1;i<=n;i++)p[i][0]=f[i];
        for(j=1;(1<<j)<=n;j++)
            for(i=1;i<=n;i++)
            if(p[i][j-1]!=-1)
            p[i][j]=p[p[i][j-1]][j-1];//i的第2^j祖先就是i的第2^(j-1)祖先的第2^(j-1)祖先
    }
    void add(int u, int v, int w) {
        edge[cnt].u=u, edge[cnt].v=v;
        edge[cnt].next=head[u], edge[cnt].val=w;
        head[u]=cnt++;
    }
    void dfs(int u, int pre, int t) {
        deep[u]=t;
        f[u]=pre;
        for (int i=head[u]; ~i; i=edge[i].next) {
            int v=edge[i].v;
           if (v!=pre) {
            dis[v]=dis[u]+edge[i].val;
            dfs(v, u, t+1);
           }
        }
    }
    int lca(int a, int b) {
        int i, j;
        if (deep[a]<deep[b])  swap(a, b);
        for ( i=0; (1<<i)<=deep[a]; i++);
        i--;
        for ( j=i; j>=0; j--) {
            if (deep[a]-(1<<j)>=deep[b])  a=p[a][j];
        }
        if (a==b)  return a;
        for ( j=i; j>=0; j--) {
            if (p[a][j]!=-1 && p[a][j]!=p[b][j]) {
                a=p[a][j], b=p[b][j];
            }
        }
        return f[a];
    }
    void solve() {
        scanf("%d%d", &n, &m);
        cnt=0;
        memset(head, -1, sizeof(head));
        for (int i=0; i<n-1; i++) {
            int a, b, c;  scanf("%d%d%d", &a, &b, &c);
            add(a, b, c);  add(b, a, c);
        }
        dis[1]=0;
        dfs(1, -1, 0);
        init();
        for (int i=0; i<m; i++) {
            int a, b;  scanf("%d%d", &a, &b);
            int ans=dis[a]+dis[b]-2*dis[lca(a, b)];
            printf("%d
    ", ans);
        }
    }
    int main() {
        int t = 1;
       // freopen("in.txt","r",stdin);
      //  freopen("gcd.out","w",stdout);
         scanf("%d", &t);
        while(t--)
            solve();
        return 0;
    }
  • 相关阅读:
    解决Mysql(MyISAM)的读写互斥锁的问题
    XtraDB存储引擎
    VMware虚拟机linux系统时间同步的解决办法centos rhel
    SQL Server数据库查询速度慢的原因和解决方法
    mysql database manual[mysql数据库手册]
    android 相机使用详解概述
    android中进行https连接的方式的详解
    android 获取手机中所有的传感器Sensor类使用方法
    获取手机安装的全部应用的示例教程
    android 全局异常的处理 详解
  • 原文地址:https://www.cnblogs.com/gggyt/p/7257162.html
Copyright © 2020-2023  润新知