• [洛谷P1967] 货车运输(最小生成树+树剖+RMQ)


    原题

    思路

    先求出最大生成树,然后对每个询问求LCA,求两点走向LCA路径上的最小权值,树剖实现,求最小值懒得写线段树用了RMQ,虽然r<l的情况没特判调了很久。还是比较简单的模板题,但是找了很久bug。

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <list>
    #include <map>
    #include <iostream>
    #include <iomanip>
    #include <queue>
    #include <set>
    #include <stack>
    #include <string>
    #include <unordered_map>
    #include <vector>
    #define LL long long
    #define inf 0x3f3f3f3f
    #define INF 0x3f3f3f3f3f3f
    #define PI 3.1415926535898
    #define F first
    #define S second
    #define endl '
    '
    #define lson rt << 1
    #define rson rt << 1 | 1
    #define lowbit(x) (x & (-x))
    #define f(x, y, z) for (int x = (y), __ = (z); x < __; ++x)
    #define _rep(i, a, b) for (int i = (a); i <= (b); ++i)
    #define _per(i, a, b) for (int i = (a); i >= (b); --i)
    using namespace std;
    
    const int maxn = 1e5 + 7;
    int head[maxn], fat[maxn], p[maxn][30];
    int n, m, q;
    inline LL read()
    {
        LL x = 0, f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9')
        {
            if (ch == '-')
                f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    struct pp
    {
        int fr, v, w;
    } edge[maxn];
    bool cmp(pp a, pp b)
    {
        return a.w > b.w;
    }
    int tot = 0;
    void add_e(int u, int v, int w)
    {
        edge[++tot].fr = u;
        edge[tot].w = w;
        edge[tot].v = v;
    }
    
    inline int fa(int x)
    {
        return fat[x] == x ? x : fat[x] = fa(fat[x]);
    }
    inline void unnion(int x, int y)
    {
        fat[fa(x)] = fa(y);
    }
    
    struct node
    {
        int fr, v, w, nxt;
    } e[maxn * 2];
    
    int num = 0;
    inline void add(int t1, int t2, int t3)
    {
        e[++num].fr = t1;
        e[num].v = t2;
        e[num].w = t3;
        e[num].nxt = head[t1];
        head[t1] = num;
    }
    
    int son[maxn], sz[maxn], f[maxn], dep[maxn];
    int w[maxn];
    inline void dfs1(int u, int fa)
    {
        sz[u] = 1;
        for (int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].v;
            if (v == fa)
                continue;
            dep[v] = dep[u] + 1;
            f[v] = u;
            dfs1(v, u);
            sz[u] += sz[v];
            if (sz[v] > sz[son[u]])
                son[u] = v;
        }
        for (int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].v;
            if (v == fa)
                continue;
        }
    }
    
    int top[maxn], in[maxn];
    int cnt = 0;
    inline void dfs2(int u, int t)
    {
        in[u] = ++cnt;
        top[u] = t;
        if (son[u])
            dfs2(son[u], t);
        for (int i = head[u]; i; i = e[i].nxt)
        {
            int v = e[i].v;
            if (v == f[u] || v == son[u])
                continue;
            dfs2(v, v);
        }
    }
    
    inline void give_val()
    {
        _rep(i, 1, num)
        {
            if (dep[e[i].fr] > dep[e[i].v])
                w[in[e[i].fr]] = e[i].w;
            else
                w[in[e[i].v]] = e[i].w;
        }
    }
    
    inline void rmq_init()
    {
        for (int i = 1; i <= cnt; i++)
        {
            p[i][0] = w[i];
        }
        for (int j = 1; (1 << j) <= cnt; j++)
        {
            for (int i = 1; i + (1 << j) - 1 <= cnt; i++)
            {
                p[i][j] = min(p[i][j - 1], p[i + (1 << (j - 1))][j - 1]);
            }
        }
    }
    inline int rmq_min(int l, int r)
    {
        if (r < l)
            return inf;
        int k = log2(r - l + 1);
        return min(p[l][k], p[r - (1 << k) + 1][k]);
    }
    
    inline int LCA(int x, int y)
    {
        int mn = inf;
        int fx = top[x], fy = top[y];
        while (fx != fy)
        {
            if (dep[fx] < dep[fy])
            {
                swap(x, y);
                swap(fx, fy);
            }
            mn = min(mn, rmq_min(in[fx], in[x]));
            x = f[fx], fx = top[x];
        }
        if (dep[x] < dep[y])
            mn = min(mn, rmq_min(in[x] + 1, in[y]));
        else
            mn = min(mn, rmq_min(in[y] + 1, in[x]));
        return mn;
    }
    
    int main()
    {
        n = read(), m = read();
        int x, y, v;
        _rep(i, 1, m)
        {
            x = read(), y = read(), v = read();
            add_e(x, y, v);
            add_e(y, x, v);
        }
        sort(edge + 1, edge + 1 + tot, cmp);
        _rep(i, 1, n) fat[i] = i;
        _rep(i, 1, tot)
        {
            if (fa(edge[i].fr) == fa(edge[i].v))
                continue;
            unnion(edge[i].fr, edge[i].v);
            add(edge[i].fr, edge[i].v, edge[i].w);
            add(edge[i].v, edge[i].fr, edge[i].w);
        }
        _rep(i, 1, n)
        {
            if (fat[i] != i)
                continue;
            dfs1(i, i);
            dfs2(i, i);
            w[in[i]] = inf;
        }
        give_val();
        q = read();
        rmq_init();
        _rep(i, 1, q)
        {
            cin >> x >> y;
            if (fa(x) != fa(y))
                cout << "-1" << endl;
            else
                cout << LCA(x, y) << endl;
        }
    }
    
  • 相关阅读:
    用JS + WCF打造轻量级WebPart
    提高WCF服务并发能力的简单处理办法
    利用JQuery实现更简单的Ajax跨域请求
    WCF Testing Tool(转)
    [转贴]一个有趣的布局
    [转贴].net中上传视频并将各种视频文件转换成.flv格式
    IE5,IE6,IE7,IE8的css兼容性列表[转自MSDN]
    [转贴]Castle 开发系列文章
    ie6,ie7,ff 的css兼容hack写法
    ExtJs学习笔记(23)ScriptTagProxy+XTemplate+WCF跨域取数据
  • 原文地址:https://www.cnblogs.com/hfcdyp/p/14091842.html
Copyright © 2020-2023  润新知