zoukankan      html  css  js  c++  java
  • HDU2874【倍增、ST】

    题目链接【https://vjudge.net/problem/HDU-2874】

    题意: 输入一个森林,总节点不超过N(N<10000),由C次询问(C<1000000),每次询问两个点,如果来联通输出,两点之间的距离,如果不来联通,输出“Not connected”;

    思路:首先判断u,v两个点在不在同一个树上,用并查集来做,如果在,就求两者的LCA,输入距离dis[u->v]=dis[u]+dis[v]-2*dis[LCA(u,v)]。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int maxn = 10050;
    int N, M, C;
    struct node
    {
        int id, next, len;
    } E[maxn << 1];
    int head[maxn << 1], num;
    void initlist()
    {
        memset(head, -1, sizeof(head));
        num = 0;
    }
    void adde(int u, int v, int len)
    {
        E[num].id = u;
        E[num].len = len;
        E[num].next = head[v];
        head[v] = num++;
    }
    //----------------------------------------邻接表
    int fa[maxn<<1];
    void initfa()
    {
        for(int i = 0; i <= N; i++)
            fa[i] = i;
    }
    int Find(int id)
    {
        if(id == fa[id]) return id;
        else return fa[id] = Find(fa[id]);
    }
    void addu(int u, int v)
    {
        int x = Find(u);
        int y = Find(v);
        if(x != y)    fa[x] = y;
    }
    //----------------------------------------并查集
    int p[16][maxn], dep[maxn], dis[maxn], vis[maxn];
    void DFS(int u, int FA)
    {
        vis[u] = 1;
        for(int l = head[u]; l != -1; l = E[l].next)
        {
            int id = E[l].id;
            if(id == FA||vis[id]) continue;
            dep[id] = dep[u] + 1;
            dis[id] = dis[u] + E[l].len;
            p[0][id] = u;
            DFS(id, u);
        }
    }
    void initlca()
    {
        memset(p, -1, sizeof(p));
        memset(dep,0,sizeof(dep));
        memset(dis, 0, sizeof(dis));
        memset(vis, 0, sizeof(vis));
        for(int i = 1; i <= N; i++)
        {
            if(!vis[i])
                DFS(i, -1);
        }
        for(int k = 0; k + 1 <= 15; k++)
            for(int u = 1; u <= N; u++)
            {
                if(p[k][u] < 0) p[k + 1][u] = -1;
                else
                    p[k + 1][u] = p[k][p[k][u]];
            }
    }
    int LCA(int u, int v)
    {
        if(dep[u] > dep[v]) swap(u, v);
        for(int k = 0; k <= 15; k++)
        {
            if((dep[v] - dep[u]) >> k & 1)
                v = p[k][v];
        }
        if(u == v) return u;
        for(int k = 15; k >= 0; k--)
        {
            if(p[k][u] != p[k][v])
            {
                u = p[k][u];
                v = p[k][v];
            }
        }
        return p[0][u];
    }
    //----------------------------------------LCA
    int main ()
    {
        while(~scanf("%d%d%d", &N, &M, &C))
        {
            initlist();
            initfa();
            int u, v, ds;
            for(int i = 1; i <= M; i++)
            {
                scanf("%d%d%d", &u, &v, &ds);
                adde(u, v, ds);
                adde(v, u, ds);
                addu(u, v);
            }
            initlca();
            for(int i=1;i<=C;i++)
            {
                scanf("%d%d",&u,&v);
                int x=Find(u);
                int y=Find(v);
                if(x==y)
                {
                    printf("%d
    ",dis[u]+dis[v]-2*dis[LCA(u,v)]);
                }
                else
                    printf("Not connected
    ");
            }
        }
        return 0;
    }
    //#include<bits/stdc++.h>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAXN = 100050;
    //---------------------------------//邻接表
    struct node
    {
        int to, len, next;
    } E[MAXN * 2];
    int p[MAXN * 2], tot;
    void init()
    {
        memset(p, -1, sizeof(p));
        tot = 0;
    }
    void add(int u, int v, int len)
    {
        E[tot].to = v;
        E[tot].len = len;
        E[tot].next = p[u];
        p[u] = tot++;
    }
    //---------------------------------//并查集
    int fa[MAXN * 2];
    void init2(int n)
    {
        for(int i = 1; i <= n; i++)
            fa[i] = i;
    }
    int Find(int x)
    {
        if(x == fa[x])
            return fa[x];
        else
            return fa[x] = Find(fa[x]);
    }
    void join (int i, int j)
    {
        int x = Find(i);
        int y = Find(j);
        if(x != y) fa[y] = x;
    }
    //----------------------------------//LAC
    int ver[MAXN * 2], vis[MAXN], fst[MAXN], R[MAXN * 2];
    int dis[MAXN], KT[MAXN * 2], dp[MAXN * 2][25];
    void init3()
    {
        memset(vis, 0, sizeof(vis));
        tot = 0;
    }
    void DFS(int u, int dep, int len)
    {
        vis[u] = 1;
        ver[++tot] = u;
        R[tot] = dep;
        fst[u] = tot;
        dis[u] = len;
        for(int k = p[u]; k != -1; k = E[k].next)
        {
            int v = E[k].to;
            if(vis[v]) continue;
            DFS(v, dep + 1, len + E[k].len);
            ver[++tot] = u;
            R[tot] = dep;
        }
    }
    void ST(int n)
    {
        KT[1] = 0;
        for(int i = 2; i <= n; i++)
            KT[i] = KT[i / 2] + 1;
        for(int i = 1; i <= n; i++)
            dp[i][0] = i;
        for(int j = 1; j <= KT[n]; j++)
            for(int i = 1; i + (1 << j) - 1 <= n; i++)
            {
                int x = dp[i][j - 1];
                int y = dp[i + (1 << (j - 1))][j - 1];
                dp[i][j] = R[x] < R[y] ? x : y;
            }
    }
    int RMQ(int l, int r)
    {
        int k = KT[r - l + 1];
        int x = dp[l][k];
        int y = dp[r - (1 << k) + 1][k];
        return R[x] < R[y] ? x : y;
    }
    int LCA(int u, int v)
    {
        int l = fst[u], r = fst[v];
        if(l > r) swap(l, r);
        int t = RMQ(l, r);
        return ver[t];
    }
    //-------------------------------------//主函数
    int N, M, C;
    int main ()
    {
        while(~scanf("%d%d%d", &N, &M, &C))
        {
            init();//
            init2(N);
            int u, v, len;
            for(int i = 1; i <= M; i++)
            {
                scanf("%d%d%d", &u, &v, &len);
                add(u, v, len);
                add(v, u, len);
                join(u, v);
            }
            init3();
            for(int i = 1; i <= N; i++)
            {
                if(vis[i]) continue;
                DFS(i, 1, 0);
            }
            ST(2 * N - 1);
            for(int i = 1; i <= C; i++)
            {
                scanf("%d%d", &u, &v);
                int x = Find(u);
                int y = Find(v);
                if(x != y)
                {
                    printf("Not connected
    ");
                    continue;
                }
                int lca = LCA(u, v);
                printf("%d
    ", dis[u] + dis[v] - 2 * dis[lca]);
            }
        }
        return 0;
    }
    想的太多,做的太少。
  • 相关阅读:
    5.2 TensorFlow:模型的加载,存储,实例
    5.2 TensorFlow:模型的加载,存储,实例
    卷积神经网络(cnn)的体系结构
    卷积神经网络(cnn)的体系结构
    Python学习笔记(四) 函数
    Python学习笔记(三) 字典
    Python学习笔记(二) 字符串
    Python学习笔记(一) 列表和元组
    Linux学习笔记(七) 查询系统
    Linux学习笔记(六) 进程管理
  • 原文地址:https://www.cnblogs.com/pealicx/p/6396961.html
Copyright © 2011-2022 走看看