zoukankan      html  css  js  c++  java
  • hdu 2874Connections between cities LCA

    题目链接

    给n个城市, m条边, q个询问, 每个询问, 输出城市a和b的最短距离, 如果不联通, 输出not connected。

    用并查集判联通, 如果不连通, 那么两个联通块之间加一条权值很大的边。 然后树链剖分.....

    #include <iostream>
    #include <vector>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <map>
    #include <set>
    #include <string>
    #include <queue>
    #include <stack>
    #include <bitset>
    using namespace std;
    #define pb(x) push_back(x)
    #define ll long long
    #define mk(x, y) make_pair(x, y)
    #define lson l, m, rt<<1
    #define mem(a) memset(a, 0, sizeof(a))
    #define rson m+1, r, rt<<1|1
    #define mem1(a) memset(a, -1, sizeof(a))
    #define mem2(a) memset(a, 0x3f, sizeof(a))
    #define rep(i, n, a) for(int i = a; i<n; i++)
    #define fi first
    #define se second
    typedef pair<int, int> pll;
    const double PI = acos(-1.0);
    const double eps = 1e-8;
    const int mod = 1e9+7;
    const int inf = 1061109567;
    const int dir[][2] = { {-1, 0}, {1, 0}, {0, -1}, {0, 1} };
    const int maxn = 10005;
    int head[maxn*2], fa[maxn], son[maxn], sz[maxn], deep[maxn], top[maxn], w[maxn], f[maxn], cnt, num;
    ll sum[maxn<<2];
    struct node
    {
        int to, nextt, w;
    }e[maxn*2];
    struct ed
    {
        int u, v;
        ll w;
        ed(){}
        ed(int u, int v, ll w):u(u),v(v),w(w){}
    }edge[maxn];
    void init() {
        mem1(head);
        num = cnt = 0;
    }
    void add(int u, int v, int w) {
        e[num].to = v, e[num].nextt = head[u], e[num].w = w, head[u] = num++;
    }
    void dfs1(int u, int fa) {
        sz[u] = 1;
        deep[u] = deep[fa]+1;
        son[u] = -1;
        f[u] = fa;
        for(int i = head[u]; ~i; i = e[i].nextt) {
            int v = e[i].to;
            if(v == fa)
                continue;
            dfs1(v, u);
            sz[u] += sz[v];
            if(son[u]==-1||sz[v]>sz[son[u]])
                son[u] = v;
        }
    }
    void dfs2(int u, int tp) {
        w[u] = ++cnt, top[u] = tp;
        if(~son[u])
            dfs2(son[u], tp);
        for(int i = head[u]; ~i; i = e[i].nextt) {
            int v = e[i].to;
            if(v == f[u]||v == son[u])
                continue;
            dfs2(v, v);
        }
    }
    void pushUp(int rt) {
        sum[rt] = sum[rt<<1]+sum[rt<<1|1];
    }
    void update(int p, ll val, int l, int r, int rt) {
        if(l == r) {
            sum[rt] = val;
            return ;
        }
        int m = l+r>>1;
        if(p<=m)
            update(p, val, lson);
        else
            update(p, val, rson);
        pushUp(rt);
    }
    ll query(int L, int R, int l, int r, int rt) {
        if(L<=l&&R>=r) {
            return sum[rt];
        }
        int m = l+r>>1;
        ll ret = 0;
        if(L<=m)
            ret += query(L, R, lson);
        if(R>m)
            ret += query(L, R, rson);
        return ret;
    }
    ll find(int u, int v) {
        int f1 = top[u], f2 = top[v];
        ll ret = 0;
        while(f1 != f2) {
            if(deep[f1]<deep[f2]) {
                swap(f1, f2);
                swap(u, v);
            }
            ret += query(w[f1], w[u], 1, cnt, 1);
            u = f[f1];
            f1 = top[u];
        }
        if(u == v)
            return ret;
        if(deep[u]>deep[v])
            swap(u, v);
        ret += query(w[son[u]], w[v], 1, cnt, 1);
        return ret;
    }
    int findd(int u) {
        return fa[u] == u?u:findd(fa[u]);
    }
    int main()
    {
        int n, m, q, x, y, z;
        while(cin>>n>>m>>q) {
            init();
            int ecnt = 0;
            for(int i = 1; i<=n; i++)
                fa[i] = i;
            for(int i = 0; i<m; i++) {
                scanf("%d%d%d", &x, &y, &z);
                add(x, y, z);
                add(y, x, z);
                edge[ecnt++] = ed(x, y, z);
                x = findd(x);
                y = findd(y);
                if(x!=y)
                    fa[x] = y;
            }
            x = findd(1);
            for(int i = 2; i<=n; i++) {
                y = findd(i);
                if(y!=x) {
                    fa[y] = x;
                    edge[ecnt++] = ed(x, y, (ll)1e12);
                    add(x, y, inf);
                    add(y, x, inf);
                }
            }
            dfs1(1, 0);
            dfs2(1, 1);
            for(int i = 0; i<ecnt; i++) {
                if(deep[edge[i].u]>deep[edge[i].v]) {
                    swap(edge[i].u, edge[i].v);
                }
                update(w[edge[i].v], edge[i].w, 1, cnt, 1);
            }
            while(q--) {
                scanf("%d%d", &x, &y);
                ll ans = find(x, y);
                if(ans>=1e12) {
                    puts("Not connected");
                } else {
                    printf("%d
    ", ans);
                }
            }
        }
    
        return 0;
    }
  • 相关阅读:
    C-net总结
    C编程经验总结4
    关于ACL中通配符掩码(反掩码)认识
    SPRITEKIT游戏框架之关于PHYSICS物理引擎属性
    (三)宇宙大战 Space Battle -- 场景SCENE切换、UserDefaults统计分数、Particle粒子效果
    SpriteKit游戏开发适配iPad/iPhone6/7/8/Plus及iPhoneX的尺寸及安全区域
    如何应用SPRITEKIT的CAMERA实现游戏中的ENDLESS无限循环背景
    iFIERO
    iFIERO
    【Swift】日期比较函数 记录下 Comparing date in Swift
  • 原文地址:https://www.cnblogs.com/yohaha/p/5094600.html
Copyright © 2011-2022 走看看