1. 程式人生 > 實用技巧 >2020牛客暑期多校訓練營(第八場)I Interesting Computer Game

2020牛客暑期多校訓練營(第八場)I Interesting Computer Game

2020牛客暑期多校訓練營(第八場)I Interesting Computer Game

題解:

用並查集寫即可。

#include <bits/stdc++.h>
#define debug(x) cout<<"debug:"<<" "<<#x<<"="<<x<<endl;
using namespace std;
const int maxn = 4e5+10;
int f[maxn],val[maxn];
int v[maxn],a[maxn],b[maxn];
int find(int x){
    return x == f[x]?x:f[x] = find(f[x]);
}
void unite(int x,int y){
    x = find(x);
    y = find(y);
    if(x==y) return ;
    f[x] = y;
    val[y]+=val[x];
    val[x] = 0;
}
bool same(int x,int y){
    return find(x) == find(y);
}
int cnt[maxn];
int main() {
    int T;
    scanf("%d", &T);
    for (int cas = 1; cas <= T; cas++) {
        int n, now = 0;
        scanf("%d", &n);
        for (int i = 1; i <= n; i++) {
            scanf("%d%d", &a[i], &b[i]);
            v[++now] = a[i], v[++now] = b[i];
        }
        sort(v + 1, v + 1 + now);
        int len = unique(v + 1, v + 1 + now) - v - 1;
        for (int i = 1; i <= len; i++) f[i] = i, val[i] = 1, cnt[i] = 0;
        for (int i = 1; i <= n; i++) {
            a[i] = lower_bound(v + 1, v + 1 + len, a[i]) - v;
            b[i] = lower_bound(v + 1, v + 1 + len, b[i]) - v;
            if (same(a[i], b[i])) val[find(a[i])]++;
            else unite(a[i], b[i]);
        }
        int ans = 0;
        for (int i = 1; i <= len; i++) cnt[find(i)]++;
        for (int i = 1; i <= len; i++) {
            if (!cnt[i]) continue;
            if (val[i] > cnt[i]) ans += cnt[i];
            else ans += cnt[i] - 1;
        }
        printf("Case #%d: %d\n", cas, ans);
    }
    return 0;
}