专栏文章

题解:P10938

P10938题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@miocw7f5
此快照首次捕获于
2025/12/02 17:08
3 个月前
此快照最后确认于
2025/12/02 17:08
3 个月前
查看原文

题目大意

给你一个 DAG,让你求出一个最大的 kk,使得这 kk 个点互相都不能到达。

解题思路

首先看到求最大值,就可以想到二分答案,然后这道题就可以转换成判断是否有 kk 个点互相不能到达。
考虑如何进行 Check。
看到 n200n \le 200 的数据范围就可以尝试用随机化,每次打乱数组顺序,能加入集合就加入集合里面,这样就可以用很简单的方法 AC 了。

Code

CPP
#include <bits/stdc++.h>

#define endl '\n'
#define rep(i,j,k) for (auto i = (j); i <= (k); ++i)
#define dwn(i,j,k) for (auto i = (j); i >= (k); --i)
#define repl(i,j,k,w) for (auto i = (j); i <= (k); i += (w))
#define dwnl(i,j,k,w) for (auto i = (j); i >= (k); i -= (w))
#define ll long long
#define ull unsigned long long

using namespace std;

constexpr int N = 291;

array <array <bool, N>, N> dis;
array <int, N> a; 

random_device rd;
mt19937 rnd (rd ());

int n, m;

//统计数量
bool _count (int cnt) {

    array <int, N> f;
    int siz = 0; 

    rep (i, 1, n) {

        rep (j, 1, siz)
            if (dis[a[f[j]]][a[i]] or dis[a[i]][a[f[j]]]) //不能加入集合,跳过
                goto end;
        
        f[++siz] = i;//加入集合
        // cout << a[i] << ' ';
        end:;
    }

    // cout << endl;

    if (siz >= cnt) return true;
    return false;
}

bool check (int value) {

    rep (i, 1, n) a[i] = i;

    rep (i, 1, 3500) {

        shuffle (a.begin () + 1, a.begin () + n + 1, rnd);//随机打乱顺序

        // rep (i, 1, n) cout << a[i] << ' ';
        // cout << endl;

        // cout << endl;

        if (_count (value)) return true;
    }

    return false;
}

int main (void) {

    ios :: sync_with_stdio (false);
    cin.tie (nullptr);
    cout.tie (nullptr);
    
    cin >> n >> m;

    rep (i, 1, m) {

        int u, v;
        cin >> u >> v;

        dis[u][v] = true;
    }

    // Floyed传递闭包
    rep (k, 1, n)
        rep (i, 1, n)
            rep (j, 1, n)
                dis[i][j] |= dis[i][k] and dis[k][j];

    int l = 0, r = n, ans = 0;

    while (l <= r) {

        int mid = l + r >> 1;

        // cout << mid << endl;

        if (check (mid)) {

            ans = mid;
            l = mid + 1;
        } else r = mid - 1;
    }

    cout << ans << endl;
    
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...