Logue P4589 [TJOI2018] intelligence competition (two point answer two point map matching)

Posted by programming_passion on Wed, 04 Dec 2019 18:55:53 +0100

meaning of the title

Title Link

Give a weighted digraph, select n + 1n+1 chains, and ask whether all points can be covered, if not, what is the minimum value of point weight that can not be covered

Sol

How to get rid of board problems in TJOI

After the binary answer, check the binary graph directly.

If you read more questions, you will find that what the questions require is the minimum path coverage that can be intersected. Then you can floyd once according to the routine, add edges in the bipartite graph if it can be connected, and then judge the maximum matching number. At first, I thought that because some points can not be selected, it is not necessary to be greedy for metaphysics when we are in Hungary, because we have asked for a pass through closure. So it's right to ask directly

Because \ (M \leqslant 500 \), Floyd needs to optimize with bitset

#include<bits/stdc++.h> 
#define Pair pair<int, int>
#define MP(x, y) make_pair(x, y)
#define fi first
#define se second
//#define int long long 
#define ull signed long long 
#define LL long long 
#define Fin(x) {freopen(#x".in","r",stdin);}
#define Fout(x) {freopen(#x".out","w",stdout);}
using namespace std;
const int MAXN = 1001, mod = 1e9 + 7, INF = 1e9 + 10;
const double eps = 1e-9;
template <typename A, typename B> inline bool chmin(A &a, B b){if(a > b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline bool chmax(A &a, B b){if(a < b) {a = b; return 1;} return 0;}
template <typename A, typename B> inline LL add(A x, B y) {if(x + y < 0) return x + y + mod; return x + y >= mod ? x + y - mod : x + y;}
template <typename A, typename B> inline void add2(A &x, B y) {if(x + y < 0) x = x + y + mod; else x = (x + y >= mod ? x + y - mod : x + y);}
template <typename A, typename B> inline LL mul(A x, B y) {return 1ll * x * y % mod;}
template <typename A, typename B> inline void mul2(A &x, B y) {x = (1ll * x * y % mod + mod) % mod;}
template <typename A> inline void debug(A a){cout << a << '\n';}
template <typename A> inline LL sqr(A x){return 1ll * x * x;}
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
int N, M, a[MAXN], ans[MAXN], vis[MAXN], tim = 1, link[MAXN], st[MAXN], top;
bitset<MAXN> can[MAXN];
bool dfs(int x) {
    for(int i = 1; i <= top; i++) {
        if(can[st[x]][st[i]]) {
            if(vis[i] == tim) continue;
            vis[i] = tim;
            if(!link[i] || (dfs(link[i]))) {link[i] = x; return 1;}
        }
    }
    return 0;
}
bool check(int val) {
    memset(link, 0, sizeof(link)); top = 0;
    for(int i = 1; i <= M; i++) if(a[i] < val) st[++top] = i;
    int ans = 0;
    for(int i = 1; i <= top; i++, tim++) if(dfs(i)) ans++;
    return top - ans <= N + 1;
}
signed main() {
    N = read(); M = read(); 
    int mx = 0;
    for(int i = 1; i <= M; i++) {
        a[i] = read(); int k = read(); mx = max(a[i], mx);
        for(int j = 1; j <= k; j++) can[i][read()] = 1;
    }
    for(int k = 1; k <= M; k++)
        for(int i = 1; i <= M; i++)
            if(can[i][k])
                can[i] |= can[k];
    int l = 0, r = mx, ans = 0;
    while(l <= r) {
        int mid = l + r >> 1;
        if(check(mid)) ans = mid, l = mid + 1;
        else r = mid - 1;
    }
    if(ans >= mx) puts("AK");
    else cout << ans;
    return 0;
}
/*

*/

Topics: C++