罗马游戏

Solution

感觉自己没学懂。。。

(mathtt{unite}) 函数只是将 x 与 y 相连,不是它们的 f 相连!所以合并的时候应该将两棵树的根合并而不是直接合并。

另外删除的时候直接将 root 的 f 设置为最优儿子就行了,因为我们是用并查集进行维护。但这同时也要注意一个问题:将儿子的 f 设置为自己,不然会有死循环。

Code

#include <cstdio>
#include <iostream>
using namespace std;
typedef long long ll;

const int N = 1e6 + 5;

int head[N], dot[N << 1], nxt[N << 1], cnt;
bool vis[N];

struct LT {
    int f[N], son[N][2], val[N], dis[N];

    void init(const int n) {
        for(int i = 1; i <= n; ++ i) {
            son[i][0] = son[i][1] = dis[i] = 0;
            f[i] = i;
        }
    }

    int Find(const int x) {return x == f[x] ? x : f[x] = Find(f[x]);}

    bool cmp(const int x, const int y) {return Find(x) == Find(y);}

    int unite(int x, int y) {
        if(! x || ! y) return x + y;
        if(val[x] > val[y]) swap(x, y);
        son[x][1] = unite(son[x][1], y); f[son[x][1]] = x;
        if(dis[son[x][0]] < dis[son[x][1]]) swap(son[x][0], son[x][1]);
        dis[x] = dis[son[x][1]] + 1;
        return x;
    }

    int del(const int x) {
        int l = son[x][0], r = son[x][1];
        son[x][0] = son[x][1] = dis[x] = 0;
        f[l] = l; f[r] = r;
        return unite(l, r);
    }

    void solve(const int x) {
        int fa = Find(x);
        printf("%d
", val[fa]);
        vis[fa] = 1;
        f[fa] = unite(son[f[fa]][0], son[f[fa]][1]);
        f[f[fa]] = f[fa];
    }
}T;

void addEdge(const int u, const int v) {
    dot[++ cnt] = v; nxt[cnt] = head[u]; head[u] = cnt;
}

int read() {
    int x = 0, f = 1; char s;
    while((s = getchar()) < '0' || s > '9') if(s == '-') f = -1;
    while(s >= '0' && s <= '9') {x = (x << 1) + (x << 3) + (s ^ 48); s = getchar();}
    return x * f;
}

int main() {
    int n = read(), m, x, y; char ch[5];
    T.init(n);
    for(int i = 1; i <= n; ++ i) T.val[i] = read();
    m = read();
    while(m --) {
        scanf("%s", ch), x = read();
        if(ch[0] == 'M') {
            y = read();
            if(vis[x] || vis[y]) continue;
            int fx = T.Find(x), fy = T.Find(y);
            if(fx != fy) T.f[fx] = T.f[fy] = T.unite(fx, fy);
        }
        else if(vis[x]) puts("0");
        else T.solve(x);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWhiteWall/p/12617704.html