• [NOIP 2013] 货车运输


    [题目链接]

               https://www.luogu.org/problemnew/show/P1967

    [算法]

            可以证明答案一定为最大生成树上两点路径中的最小值

            树上倍增即可

            时间复杂度 : O((N + Q) log N)
    [代码]

             

    #include<bits/stdc++.h>
    using namespace std;
    #define MAXN 10010
    #define MAXM 50010
    #define MAXLOG 20
    const int inf = 2e9;
    
    struct info
    {
        int u,v,w;
    } a[MAXM];
    struct edge
    {
        int to,w,nxt;
    } e[MAXM << 1];
    
    int i,n,m,u,v,w,x,y,tot,cnt,q;
    int fa[MAXN],color[MAXN],head[MAXN],depth[MAXN];
    int anc[MAXN][MAXLOG],mn[MAXN][MAXLOG];
    bool visited[MAXN];
    
    namespace IO
    {
        template <typename T> inline void read(T &x)
        {
            int f = 1; x = 0;
            char c = getchar();
            for (; !isdigit(c); c = getchar())
            {
                if (c == '-') f = -f;
            }
            for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
            x *= f;
        }
        template <typename T> inline void write(T x)
        {
            if (x < 0)
            {
                putchar('-');
                x = -x;
            }
            if (x > 9) write(x / 10);
            putchar(x % 10 + '0');
        }
        template <typename T> inline void writeln(T x)
        {
            write(x);
            puts("");
        }
    } ;
    inline bool cmp(info a,info b)
    {
        return a.w > b.w;
    }
    inline void addedge(int u,int v,int w)
    {
        tot++;
        e[tot] = (edge){v,w,head[u]};
        head[u] = tot;
    }
    inline int get_root(int x)
    {
        if (fa[x] == x) return x;
        return fa[x] = get_root(fa[x]);
    }
    inline void kruskal()
    {
        int i,su,sv,u,v,w;
        sort(a + 1,a + m + 1,cmp);
        for (i = 1; i <= m; i++)
        {
            u = a[i].u; v = a[i].v; w = a[i].w;
            su = get_root(u);
            sv = get_root(v);
            if (su != sv) 
            {
                fa[sv] = su;
                addedge(u,v,w);
                addedge(v,u,w);
            }
        }
    }
    inline void dfs(int u,int id)
    {
        int i,v,w;
        color[u] = id;
        visited[u] = true;
        for (i = 1; i < MAXLOG; i++)
        {
            anc[u][i] = anc[anc[u][i - 1]][i - 1];
            mn[u][i] = min(mn[u][i - 1],mn[anc[u][i - 1]][i - 1]);
        }
        for (i = head[u]; i; i = e[i].nxt)    
        {
            v = e[i].to;
            w = e[i].w;
            if (!visited[v]) 
            {
                depth[v] = depth[u] + 1;
                anc[v][0] = u;
                mn[v][0] = w;
                dfs(v,id);
            }
        }
    }
    inline int query(int x,int y)
    {
        int i,t;
        int ret = inf;
        if (color[x] != color[y]) return -1;
        if (depth[x] > depth[y]) swap(x,y);
        t = depth[y] - depth[x];
        for (i = 0; i < MAXLOG; i++)
        {
            if (t & (1 << i))
            {
                ret = min(ret,mn[y][i]);
                y = anc[y][i];
            }
        }
        if (x == y) return ret;
        for (i = MAXLOG - 1; i >= 0; i--)
        {
            if (anc[x][i] != anc[y][i])
            {
                ret = min(ret,min(mn[x][i],mn[y][i]));
                x = anc[x][i];
                y = anc[y][i];
            }
        } 
        if (depth[x] == 0) return ret;
        ret = min(ret,min(mn[x][0],mn[y][0]));
        return ret;
    }
    
    int main()
    {
        
        IO :: read(n); IO :: read(m);
        for (i = 1; i <= m; i++)
        {
            IO :: read(a[i].u); IO :: read(a[i].v);
            IO :: read(a[i].w);
        }
        for (i = 1; i <= n; i++) fa[i] = i;
        kruskal();
        for (i = 1; i <= n; i++)
        {
            if (!visited[i]) 
                dfs(i,++cnt);
        }
        IO :: read(q);
        while (q--)
        {
            IO :: read(x); IO :: read(y);
            IO :: writeln(query(x,y));    
        }
        
        return 0;
    }

            

  • 相关阅读:
    RTB
    urllib.error.HTTPError: HTTP Error 403: Forbidden
    HTTP请求过程详解
    python中用filter求素数
    python把str转换为int
    如何判断一个GPS点是否在以另一个GPS点为圆心100米为半径的圆内(Java代码)
    word2010表格中的内容怎么设置行距
    java创建二叉树并实现非递归中序遍历二叉树
    java创建二叉树并递归遍历二叉树
    极客DIY:打造属于自己的无线移动渗透测试箱
  • 原文地址:https://www.cnblogs.com/evenbao/p/9463729.html
Copyright © 2020-2023  润新知