NOIP 2022建造军营暴力求调

题目总版

hanss6 @ 2024-11-22 16:38:07

枚举,用并查集来判断图的连通性,样例过不了,求调

#include<bits/stdc++.h>
using namespace std;
#define int long long

const int mod = 1e9 + 7, N = 32;

int fa[N], n, m, ans;
bool d[N], b[N];

struct edge{
    int from, to;
} e[N];

int find(int x) {
    if (fa[x] == x) return x;
    return fa[x] = find(fa[x]);
}

void merge(int x, int y) {
    int f1 = find(x), f2 = find(y);
    if (f1 != f2) 
        fa[f2] = f1;
}
int now[N];
bool check() {
    for (int i = 1; i <= n; i++) fa[i] = i, now[i] = 0;
    int cnt = 0;
    for (int i = 1; i <= m; i++) {
        if (b[i]) {
            merge(e[i].from, e[i].to);
        }
    }
    for (int i = 1; i <= n; i++) {
        if (d[i]) {
            now[++cnt] = i;
        }
    }
    for (int i = 2; i <= cnt; i++) {
        if (find(now[i]) != find(now[i - 1]) ) return 0;
    }
    return 1;
}

void meijub(int deep) {
    if (deep > m) {
        if (check()) ans++;
        return; 
    }
    b[deep] = 0;
    meijub(deep + 1);
    b[deep] = 1;
    meijub(deep + 1);
    return;
}
int isd = 0;
void meijud(int deep) {
    if (deep > n) {
        if (isd == 0) {
            isd = 1;
            return;
        }
        meijub(1);
        return;
    }
    d[deep] = 0;
    meijud(deep + 1);
    d[deep] = 1;
    meijud(deep + 1);
    return;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
        cin >> e[i].from >> e[i].to;
    }
    meijud(1);
    cout << ans;

    return 0;
}

by xxseven @ 2024-11-22 16:47:06

@hanss6 貌似读题错误?方案合法的条件是在未看守的边中任意删除一个后,所有军营点连通,不是所有看守的边使军营点连通。

如果要把这个暴力改对,枚举删哪条边应该就可以了。


by hanss6 @ 2024-11-22 16:54:45

@xxseven okok,我懂了


|