CF 976F Minimal k-covering

2023-05-16

          • 传送门
          • 题目大意
            • 输入格式
            • 输出格式
          • 思路
          • 参考代码

传送门
题目大意

给你一张二分图 G=(U,V,E) G = ( U , V , E ) U U 是图的 X 部, V V 是图的 Y 部, E E 是边集,可能有重边。

我们称 E 的某个子集 E¯¯¯¯ E ¯ k-覆盖 的,当且仅当图 G¯¯¯¯=(U,V,E¯¯¯¯) G ¯ = ( U , V , E ¯ ) 的每个顶点至少连接了 k k 条边;若 E¯ 是 k-覆盖 的且不存在元素个数比它更小的边集也是 k-覆盖 的,则称 E¯¯¯¯ E ¯ 是一个 最小k-覆盖

你的任务是对于所有 k[0,minDegree] k ∈ [ 0 , m i n D e g r e e ] ,求出 最小k-覆盖,其中 minDegree m i n D e g r e e 是图 G G 的所有点度数的最小值。

输入格式

第一行输入三个整数 n1 n2 n 2 m m 1n1,n22000 0m2000 0 ≤ m ≤ 2000 ),分别代表 U U 的点数,V 的点数和边数。

接下来 m m 行每行两个整数 ui vi v i ,表示第 i i 条边在 U 中的端点为 ui u i ,在 V V 中的端点为 vi

输出格式

输出包含 minDegree+1 m i n D e g r e e + 1 行,每行首先输出一个整数 cntk c n t k ,表示 最小k-覆盖 的边集大小,紧接着输出 cntk c n t k 个整数,表示属于 最小k-覆盖 的边的标号。边按输入顺序从 1 1 开始标号。输出时不必按标号从小到大输出。

思路

  唉,我太弱了,什么都不会,这么简单的傻逼题都做不来。

  一开始我想可以跑一个带上下界的最小费用流,发现好像对于每个 k 都要重新跑,怕是凉了。唉,我太弱啦!

  需要发现这么一个性质:如果源点向 X X 部的连边以及 Y 部向汇点的连边的容量都是对应点的度数,则一定满流,因为一个流量就对应一条边。我们考虑反着做:令源点或汇点的边的容量为对应点的度数减去 k k ,然后跑最大流。最大流中没有流量的边就是我们要选的边。

  显然,由于每个点的对应的容量变小了,因此肯定有对应边不能增广,也就满足了度数至少为 k 的条件。由于跑的是最大流,因此得到的答案中删的边也是最多的,这使得留下的边最小。

  我们从大到小枚举 k k ,每次在上一次的基础上继续增广。由于增广次数不超过 m 次,因此时间复杂度为 O((n+m)m) O ( ( n + m ) m )

参考代码
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <cassert>
#include <cctype>
#include <climits>
#include <ctime>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <set>
#include <bitset>
#include <list>
#include <functional>
typedef long long LL;
typedef unsigned long long ULL;
using std::cin;
using std::cout;
using std::endl;
typedef int INT_PUT;
INT_PUT readIn()
{
    INT_PUT a = 0; bool positive = true;
    char ch = getchar();
    while (!(ch == '-' || std::isdigit(ch))) ch = getchar();
    if (ch == '-') { positive = false; ch = getchar(); }
    while (std::isdigit(ch)) { a = a * 10 - (ch - '0'); ch = getchar(); }
    return positive ? -a : a;
}
void printOut(INT_PUT x)
{
    char buffer[20]; int length = 0;
    if (x < 0) putchar('-'); else x = -x;
    do buffer[length++] = -(x % 10) + '0'; while (x /= 10);
    do putchar(buffer[--length]); while (length);
}

const int INF = (~(int(1) << (sizeof(int) * 8 - 1))) >> 1;
const int maxn = 2005;
int n1, n2, m;

struct NetworkFlow
{
    struct Edge
    {
        int from, to, cap, flow;
        Edge() {}
        Edge(int from, int to, int cap) : from(from), to(to), cap(cap), flow() {}
    };
    std::vector<Edge> edges;
    std::vector<std::vector<int> > G;
    void addEdge(int from, int to, int cap)
    {
        edges.push_back(Edge(from, to, cap));
        edges.push_back(Edge(to, from, 0));
        int i = edges.size();
        G[from].push_back(i - 2);
        G[to].push_back(i - 1);
    }
    int s, t;

    struct Queue
    {
        int c[maxn * 2];
        int head, tail;
        Queue() { clear(); }
        void clear() { head = tail = 0; }
        void push(int x) { c[tail++] = x; }
        void pop() { head++; }
        int front() { return c[head]; }
        bool empty() { return head == tail; }
    } q;
    int vis[maxn * 2];
    int opt[maxn * 2];
    int pre[maxn * 2];
    bool BFS()
    {
        q.clear();
        static int stamp;
        stamp++;
        memset(opt, 0, sizeof(opt));
        opt[s] = INF;
        vis[s] = stamp;
        q.push(s);
        while (!q.empty())
        {
            int from = q.front();
            q.pop();
            for (int i = 0; i < G[from].size(); i++)
            {
                const Edge& e = edges[G[from][i]];
                if (e.flow < e.cap && vis[e.to] != stamp)
                {
                    opt[e.to] = std::min(opt[from], e.cap - e.flow);
                    pre[e.to] = G[from][i];
                    vis[e.to] = stamp;
                    q.push(e.to);
                    if (vis[t] == stamp)
                    {
                        q.clear();
                        break;
                    }
                }
            }
        }
        if (vis[t] != stamp) return false;
        for (int u = t; u != s; u = edges[pre[u]].from)
        {
            edges[pre[u]].flow += opt[t];
            edges[pre[u] ^ 1].flow -= opt[t];
        }
        return true;
    }

    void maxFlow()
    {
        while (BFS());
    }

    NetworkFlow() {}
} nf;

int base;
void statistic(std::vector<int>& ans)
{
    nf.maxFlow();
    for (int i = 1; i <= m; i++)
        if (!nf.edges[(i - 1) << 1].flow)
            ans.push_back(i);
}

int minDegree = INF;
int degree[maxn * 2];
std::vector<std::vector<int> > ans;

void run()
{
    n1 = readIn();
    n2 = readIn();
    m = readIn();
    nf.G.resize(n1 + n2 + 2);
    nf.s = 0;
    nf.t = n1 + n2 + 1;

    for (int i = 1; i <= m; i++)
    {
        int u = readIn();
        int v = readIn() + n1;
        degree[u]++;
        degree[v]++;
        nf.addEdge(u, v, 1);
    }
    for (int i = 1; i <= n1 + n2; i++)
        minDegree = std::min(minDegree, degree[i]);
    int base = (nf.edges.size() >> 1) - 1;

    for (int i = 1; i <= n1; i++)
        nf.addEdge(nf.s, i, degree[i] - minDegree);
    for (int i = 1; i <= n2; i++)
        nf.addEdge(n1 + i, nf.t, degree[n1 + i] - minDegree);

    ans.resize(minDegree + 1);
    statistic(ans[minDegree]);
    for (int i = minDegree - 1; ~i; i--)
    {
        for (int j = 1; j <= n1 + n2; j++)
            nf.edges[(base + j) << 1].cap++;
        statistic(ans[i]);
    }

    for (int i = 0; i <= minDegree; i++)
    {
        printOut(ans[i].size());
        for (int j = 0; j < ans[i].size(); j++)
        {
            putchar(' ');
            printOut(ans[i][j]);
        }
        putchar('\n');
    }
}

int main()
{
    run();
    return 0;
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

CF 976F Minimal k-covering 的相关文章

  • LaTeX 005:删除一个命令

    C 43 43 的预编译系统中 xff0c 可以使用 undef 来取消 xff08 Undefine xff09 一个宏 LaTeX LaTeX L A T E X 中是否有类似于这样的功能呢 xff1f 网上的一个评论给出了解决方案 x
  • LaTeX 006:添加一个只有文字没有标号的脚标

    想要如下的效果 xff1a 该脚标只想要写一句注释 xff0c 没有对应的正文文本 如何实现 xff1f 直接使用 footnotetext 是不佳的 xff0c 前面会加上当前的脚标标号 xff0c 而且该标号不会自动递增 虽然 foot
  • GetExitCodeProcess 所需运行时间

    GetExitCodeProcess 在 Windows 中用于获取进程的返回代码 这个看上去只有一个读操作的函数运行速度如何呢 xff1f 直觉上不会很快 xff0c 因为它肯定涉及操作系统进程表的操作 下面做了一个实验 代码 xff1a
  • C++ 继承时返回值或参数的类型是父类的行为

    见以下代码的 base t amp operator 61 const base t amp another 还没有搞清楚 span class token macro property span class token directive
  • LaTeX 007:texify 调用 zhmakeindex

    如文档所述 xff0c 在系统增加一个值为 zhmakeindex 路径的环境变量 MAKEINDEX 即可
  • 转载:LaTeX 定义参数变长的命令

    本文作者 xff1a Liam Huang 本文链接 xff1a https liam page 2017 07 30 define a new command with different amount of parameters in
  • 一个简单的 Lex 词法分析程序示例

    作为一个学习 Lex 词法分析程序的例子 xff0c 下面的 lex 程序将会生成一个分析 LaTeX 中命令的词法分析器 下面的程序包含了很多 lex 语言的语法 xff0c 正则表达式除外 正则表达式的用法网上比较多 xff0c 这里不
  • mysql数据库conf配置详解

    mysqld port 61 6033 skip grant tables datadir 61 usr tools mysql data socket 61 usr tools mysql mysql sock user 61 mysql
  • LaTeX 008:比较方便的键入下划线的方式

    在 LaTeX 中 xff0c 我们有时会需要输入下划线 直接键入 是不行的 xff0c 会出现的编译错误 xff0c 正如网友所述 xff0c LaTeX 为了简化对编译错误的处理禁止在文本模式 xff08 text mode xff09
  • LaTeX 009:自定义带有 * 号的命令

    LaTeX 中 xff0c 我们经常见到 section 和 section xff0c 分别表示有编号的 section 和没有编号的 section 我们也想自己定义带有 号的命令 xff0c 但写下面的代码时却报错了 xff1a ne
  • 2022 New Year‘s Resolution

    Some Might Say 2022 New Year 39 s Resolution Some might say we are on the edge of the new era Always are they saying thi
  • C++ 多线程编程导论(中)

    受篇幅限制 xff0c 上半部分不再更新 xff0c 填坑的新内容都放在此文章中 文章目录 参考资料线程安全 xff08 续 xff09 互斥访问 互斥体 xff08 mutex xff09 和锁 xff08 lock xff09 什么是互
  • C++ 使用模板序列化/反序列化固定键值对

    仅是一个原型 xff0c 留作记录 我感觉可以写出非常逆天的代码 span class token macro property span class token directive hash span span class token d
  • 编译原理习题两则(龙书,写出语言的正则定义)

    3 3 5 3 注释 xff0c 即 和 之间的串 xff0c 且串中没有不在双引号 xff08 34 xff09 中的 注 xff1a 假设双引号是匹配的 思路 xff1a 从空串开始写 xff0c 写出整体框架后 xff0c 通过分类讨
  • 2023 New Year‘s Resolution

    This Is Game 2023 New Year 39 s Resolution My 2022 ended with a day of game I am convinced that I am not to blame becaus
  • 补录:2018 和 2019 New Year‘s Resolution

    前言 xff1a 吉光片羽 xff0c 以飨读者 2018 New Year 39 s Resolution One year and a half ago I felt that life in 2020 would be quite d
  • 原博文地址

    由于账号问题 xff0c 现更改为这个账号 xff0c 以下为原博文地址 使用WH MOUSE LL钩子来判断按键是否是mouse event模拟的 http blog csdn net qq 26140973 article detail
  • [NOI 2003] 文本编辑器 Splay 维护序列 / 块状链表

    传送门 xff08 JZOJ xff09 xff08 第一道全国决赛题 xff09 解法 1 xff1a 使用 Splay 维护 不管怎么说 xff0c 总和刚刚学过的迎合上了 这道题可以直接上 Splay 维护线性序列 xff0c 光标位

随机推荐

  • 一次macOS的升级填坑(macOS Catalina - macOS Monterey)

    目录 小序一 升级前操作二 升级中三 问题填坑1 像我一样长时间卡在一个进度条怎么办2 在更新途中重启过电脑 xff08 完整流程填坑 xff09 3 安装之后不能开机 xff0c 如何紧急拷贝资料4 安装不成功 xff0c 如何重新安装系
  • CF 713C Sonya and Problem Wihtout a Legend

    文章目录 传送门题目大意正解通过维护关键点来维护信息参考代码 传送门 题目大意 给定一个长度为 n n 3000
  • Luogu 3642 [APIO 2016] 烟火表演

    传送门引例 xff08 上一道题 xff09 凸函数一开始的思路正解参考代码总结 传送门 引例 xff08 上一道题 xff09 凸函数 回忆我们上一道题是怎么做的 我们维护的东西的实质是一个 xff08 下 xff09 凸函数 由于我们的
  • Luogu 3631 [APIO 2011] 方格染色

    传送门思路参考代码细节 传送门 思路 很不错的一道题 xff0c 用到的东西不深 xff0c 但是要想到确实需要一定思维 一开始我想的是动态规划 xff0c 发现如果要设状态需要知道一个格子左边 xff0c 上边和左上边三个格子的状态 然后
  • Luogu 3632 [APIO 2011] 寻路

    传送门正解参考代码 传送门 正解 暴力连边跑最短路就好了 xff0c 只不过代码太长太难写啦 xff01 参考代码 span class hljs preprocessor include lt cstdio gt span span cl
  • Luogu 3634 [APIO 2012] 守卫

    传送门思路正解参考代码 传送门 思路 感觉自己越来越笨了 首先 xff0c 很明显这道题需要把没有看到忍者的区间给删去 xff0c 可以用前缀和 O n O n 处理 xff0c 然后对没有删去的地方重新标号 重新标号时 xff0c 需要对
  • Luogu 1552 [APIO 2012] 派遣

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题读错了两次 xff0c 一开始读成了一个一般的背包 xff0c 然后读成了一个价值和花费相同的背包 xff0c 最后才发现原来是一个价值为 1
  • 贪玩 CF 之旅

    文章目录 CF 7D Palindrome Degree http codeforces com problemset problem 7 D 题解 CF 713C Sonya and Problem Wihtout a Legend ht
  • Luogu 3638 [APIO 2013] 机器人

    传送门思路正解参考代码关于 SPFA 传送门 思路 n n 这么小 会不会是搜索题 稍有经验的我直接否定了这个结论 仔细读题并分析样例 发现原来一个位置可以有多个机器人 且机器人行走的时候无视其它机器人 那这个就是一张图啊 可以将这张图预处
  • Luogu 3647 [APIO 2014] 连珠线

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 又看错题了 题目中说一个新的珠子和一个已经添加的珠子连接起来 xff0c 我没有看到 xff0c 然后就凉了 立个 flag xff1a 已经连续看错五题了 xff0c
  • 【转】mingw64的安装方法

    转自 xff1a http write blog csdn net postlist mingw64的安装方法 1 下载ming w64 http sourceforge net projects mingw w64 files or x8
  • Luogu 3645 [APIO 2015] 雅加达的摩天楼

    传送门思路正解参考代码Update 传送门 思路 唉 xff0c 我太弱了 xff0c 我都看出来要分块了 xff0c 就是做不来 不过终于把题读对了 先来看子任务三怎么做 显然可以有一个 O m 2 O m 2
  • Luogu 3644 [APIO 2015] 八邻旁之桥

    传送门思路当 k 61 2 时参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题也做不来 很明显这道题先要把不过河的人排除了 xff0c 剩下的都是要过河的 当 k 61 1 k 61 1 时 xff0
  • Luogu 3646 [APIO 2015] 巴厘岛的雕塑

    传送门总结 APIO 2015思路参考代码总结 传送门 总结 APIO 2015 争取今天做完一套 QAQ T1 我最多之能想到从高位向低位做 xff0c 然后就完全不会了 xff1b T2 我想到了分情况讨论 xff0c 但是没有建图成功
  • UOJ 2016 [APIO 2016] Gap

    传送门思路参考代码交互题 交互题大致形式Windows 平台下 xff08 Dev C 43 43 xff09 Ubuntu 平台下 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 xff0c 题也做不来 这道题简直就是利用
  • CF 940F Machine Learning

    传送门题目大意思路参考代码Remarks 传送门 题目大意 给你一个数组 a 1 n n 10 5 a 1 n
  • CF 976D Degree Set

    传送门题目大意思路参考代码总结 传送门 题目大意 给你一个长度为 n n 的正整数序列 d 1 d 2 d n d1 d2 dn xff08 d 1 lt d 2 lt lt d n
  • Luogu 3778 [APIO 2017] 商旅

    传送门思路参考代码 传送门 思路 唉 xff0c 我太弱了 xff0c 什么都不会 看到这道题就想到了二分答案找负环 xff0c 但是怎么做呢 xff1f 完全不会 唉 xff0c 我太弱啦 xff01 先注意题目中说可以重复经过点和边 x
  • CF 963E Circles of Waiting

    传送门题目大意思路参考代码 传送门 题目大意 在平面直角坐标系上 xff0c 有一个神奇的点 xff0c 一开始在 0 0 0 0 每秒钟这个点都会随机移动 xff1a 如果它在 x y
  • CF 976F Minimal k-covering

    传送门题目大意 输入格式输出格式 思路参考代码 传送门 题目大意 给你一张二分图 G 61 U V E G 61 U V