[SHOI2014] magic compound

Posted by GESmithPhoto on Mon, 04 Nov 2019 20:50:40 +0100

At a glance, it's a dynamic picture (kouhu.jpg

All of the above is false news...

In fact, this problem is an obvious technical (xia) Qiao (gao) problem. We find that the number of questions is far less than the number of sides, which shows that some sides have always existed.. So we can do it offline. We can shrink the graph composed of the existing edges, and then start violent maintenance to add and delete edges.. Pay attention to using counter to record the double edge, instead of constantly adding edge.

It's better to judge the self ring again. Someone has created the hack data with self ring.. It seems that many people are still stuck..

#include <bits/stdc++.h>
#define mp make_pair
using namespace std;

int lst[5005], to[100005], pre[100005], tot,in[5005][5005], iu[200005], iv[200005], qu[10005], qv[10005], idx[5005], fa[5005], cnt;
char tp[10005];
bool vis[5005], del[100005];

map<int, pair<int, int> > edge[5005];

inline void add_edge(int u, int v) {
    if (edge[u].count(v) && edge[u][v].first) {
        edge[u][v].first++;
        return;
    }
    edge[u][v] = mp(1, tot);
    to[tot] = v;
    pre[tot] = lst[u];
    lst[u] = tot++;
}

int findf(int u) {
    if (u == fa[u]) return u;
    return fa[u] = findf(fa[u]);
}

void dfs(int u) {
    vis[u] = true;
    for (int i = lst[u]; ~i; i = pre[i]) {
        if (!del[i] && !vis[to[i]])
            dfs(to[i]);
    }
}

int main() {
    memset(lst, -1, sizeof lst);
    int n, m;
    scanf("%d%d", &n, &m);
    for (int i = 0; i < m; i++) {
        scanf("%d%d", iu + i, iv + i);
        in[--iu[i]][--iv[i]] = 1;
        in[iv[i]][iu[i]] = 1;
    }
    int q;
    scanf("%d", &q);
    for (int i = 0; i < q; i++) {
        scanf(" %c", tp + i);
        if (tp[i] != 'Q') {
            scanf("%d%d", qu + i, qv + i);
            qu[i]--;
            qv[i]--;
            if (tp[i] == 'D') in[qu[i]][qv[i]] = in[qv[i]][qu[i]] = 0;
        }
    }
    for (int i = 0; i < n; i++) fa[i] = i;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            if (in[i][j]) fa[findf(i)] = findf(j);
    for (int i = 0; i < n; i++)
        if (findf(i) == i) idx[i] = cnt++;
    for (int i = 0; i < n; i++) idx[i] = idx[fa[i]];
    memset(in, false, sizeof in);
    for (int i = 0; i < m; i++) {
        int u = idx[iu[i]], v = idx[iv[i]];
        if (u != v) {
            add_edge(u, v);
            add_edge(v, u);
        }
    }
    for (int i = 0; i < q; i++)
        if (tp[i] == 'Q') {
            memset(vis, false, cnt);
            int ans = 0;
            for (int j = 0; j < cnt; j++) {
                if (!vis[j]) {
                    ans++;
                    dfs(j);
                }
            }
            printf("%d\n", ans);
        } else if (tp[i] == 'A') {
            int u = idx[qu[i]], v = idx[qv[i]];
            if (u != v) {
                add_edge(u, v);
                add_edge(v, u);
            }
        } else {
            int u = idx[qu[i]], v = idx[qv[i]];
            if (u == v) continue;
            edge[u][v].first--;
            edge[v][u].first--;
            if (!edge[u][v].first) del[edge[u][v].second] = del[edge[v][u].second] = true;
        }
}

Personal feeling shoi is not a special cancer?

Topics: PHP less