• [TJOI 2018]智力竞赛


    Description

    题库链接

    给出一张 (m) 个点的有向图。问可重最小路径覆盖是否 (leq n+1) 。若不,求最多用 (n+1) 条路径去覆盖,最大化未覆盖点点权最小值。

    (1leq nleq 50,1leq mleq 500)

    Solution

    ( ext{floyd}) 传递闭包之后做最小路径覆盖...

    若无解,考虑二分未覆盖点点权最小值,将点权小于 (mid) 的点加入图中做最小路径覆盖。

    写这题其实是打 ( ext{dinic}) 板子的...

    Code

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 500+5, inf = ~0u>>1;
    
    int n, m, G[N][N], v[N], k, u;
    struct tt {int to, next, cap; }edge[N*N<<1];
    int path[N<<1], top, S = (N<<1)-2, T = (N<<1)-1;
    int sta[N<<1], cur[N<<1], dist[N<<1];
    queue<int>Q;
    
    bool bfs() {
        memset(dist, -1, sizeof(dist));
        Q.push(S); dist[S] = 1;
        while (!Q.empty()) {
            int u = Q.front(); Q.pop();
            for (int i = path[u], v; ~i; i = edge[i].next)
                if (dist[v = edge[i].to] == -1 && edge[i].cap > 0)
                    Q.push(v), dist[v] = dist[u]+1;
        }
        return dist[T] != -1;
    }
    int dinic() {
        int totflow = 0;
        while (bfs()) {
            int u = S; top = 0; memcpy(cur, path, sizeof(cur));
            while (1) {
                if (u == T) {
                    int loc, minflow = inf;
                    for (int i = 1; i <= top; i++) if (edge[sta[i]].cap < minflow) minflow = edge[sta[loc = i]].cap;
                    for (int i = 1; i <= top; i++) edge[sta[i]].cap -= minflow, edge[sta[i]^1].cap += minflow;
                    totflow += minflow; u = edge[sta[loc]^1].to, top = loc-1;
                }
                for (int &i = cur[u], v; ~i; i = edge[i].next)
                    if (dist[v = edge[i].to] == dist[u]+1 && edge[i].cap > 0) {
                        sta[++top] = i, u = v; break;
                    }
                if (cur[u] == -1) {
                    if (top == 0) break;
                    dist[u] = -inf; u = edge[sta[top--]^1].to; 
                } 
            }
        }
        return totflow;
    }
    void add(int u, int v, int c) {
        edge[++top] = (tt){v, path[u], c}; path[u] = top;
        edge[++top] = (tt){u, path[v], 0}; path[v] = top;
    }
    bool judge(int mid) {
        memset(path, top = -1, sizeof(path)); int cnt = 0;
        for (int i = 1; i <= m; i++) add(S, i, 1), add(i+N-5, T, 1);
        for (int i = 1; i <= m; i++)
            if (v[i] < mid) {
                ++cnt;
                for (int j = 1; j <= m; j++)
                    if (v[j] < mid && G[i][j])
                        add(i, j+N-5, 1);
            }
        return cnt-dinic() <= n+1;
    }
    void work() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= m; i++) {
            scanf("%d%d", &v[i], &k);
            for (int j = 1; j <= k; j++) scanf("%d", &u), G[i][u] = 1;
        }
        for (int k = 1; k <= m; k++)
            for (int i = 1; i <= m; i++)
                for (int j = 1; j <= m; j++)
                    G[i][j] |= (G[i][k]&G[k][j]);
        if (judge(1000000000+1)) {puts("AK"); return; }
        int L = 0, R = 1e9, ans;
        while (L <= R) {
            int mid = (L+R)>>1;
            if (judge(mid)) ans = mid, L = mid+1;
            else R = mid-1;
        }
        printf("%d
    ", ans);
    }
    int main() {work(); return 0; }
  • 相关阅读:
    springboot的整合篇-springmvc,mybatis,数据库等
    快速搭建springboot工程
    Git常用命令
    SpringBoot整合通用Mapper
    SpringBoot项目部署
    实例化调用和静态方式调用的区别
    CentOS系统安装PHP7.3
    CentOS7部署LNMP环境
    Apache和Nginx的区别
    Linux系统下卸载MySQL
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/9314251.html
Copyright © 2020-2023  润新知