简要题意是找到一条边连接使得最大团大小增加。

在补图上最大团等于最大独立集。

所以问题转化为删掉一条边使得最大独立集增加,又因为团不超过两个,所以原图是二分图,也就是使得最大匹配减少。

考虑什么样的匹配边是可以被代替的,先跑一遍网络流求最大匹配,不难发现假若一条匹配在残量网络流上的一个环中,那么它就是可以被代替的,所以对残量网络进行缩点,两个端点不在同一个强连通分量中的匹配边可以作为答案。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e4 + 114;
const int maxm = 2e6 + 114;
const int inf = 0x3f3f3f3f;
int maxflow, vis[maxn], tot = 1, cnt;
int s, t, n, m, Q, E;
vector<int> edge[maxn], Road[maxn];
int hd[maxn], road[maxn], dis[maxn];
map<int, int> f[maxn];
struct edge {
int next, to, w;
} e[maxm * 2];
void add(int u, int v, int w) {
e[++tot].to = v;
f[u][v] = tot;
e[tot].w = w;
e[tot].next = hd[u];
hd[u] = tot;
e[++tot].to = u;
e[tot].w = 0;
e[tot].next = hd[v];
hd[v] = tot;
}
bool bfs() {
memset(dis, 0, sizeof(dis));
dis[s] = 1;
queue<int>Q;
Q.push(s); while (!Q.empty()) {
int u = Q.front();
Q.pop();
road[u] = hd[u]; for (int i = hd[u]; i; i = e[i].next) {
int v = e[i].to; if (!dis[v] && e[i].w) {
dis[v] = dis[u] + 1;
Q.push(v);
} }
} return dis[t] != 0;
}
int dinic(int now, int res) {
if (now == t)
return res; int tp = res; for (int i = road[now]; i; i = e[i].next) {
int v = e[i].to;
road[now] = i; if (dis[v] == dis[now] + 1 && e[i].w) {
int k = min(e[i].w, tp);
int del = dinic(v, k);
e[i].w -= del;
e[i ^ 1].w += del;
tp -= del; if (!tp)
break;
}
} return res - tp;
}
int col[maxn], Use[maxn];
void dfs(int u) {
if (Use[u] == 1)
return ; Use[u] = 1; for (int v : edge[u])
col[v] = col[u] ^ 1, dfs(v);
}
int dfsn[maxn];
int low[maxn];
stack<int> S;
int Vis[maxn], use[maxn];
int color[maxn], sum = 0;
int deep = 0;
void paint(int u) {
S.pop();
color[u] = sum;
Vis[u] = 0;
}
void tanjan(int u) {
dfsn[u] = ++deep;
low[u] = deep;
Vis[u] = 1;
use[u] = 1;
S.push(u); for (int i = hd[u]; i; i = e[i].next) {
if (e[i].w == 0)
continue; int v = e[i].to; if (dfsn[v] == 0) {
tanjan(v);
low[u] = min(low[u], low[v]);
} else {
if (Vis[v] != 0) {
low[u] = min(low[u], low[v]);
}
}
} if (dfsn[u] == low[u]) {
sum++; while (S.top() != u) {
paint(S.top());
} paint(u);
} return ;
}
set< pair<int, int>> chifan;
int main() {
cin >> n >> m; for (int i = 1; i <= m; i++) {
int u, v;
cin >> u >> v;
edge[u].push_back(v);
edge[v].push_back(u);
} for (int i = 1; i <= n; i++) {
if (Use[i] == 0)
col[i] = 0, dfs(i);
} for (int i = 1; i <= n; i++) {
if (col[i] == 0) {
for (int nxt : edge[i])
Road[i].push_back(nxt), add(i, nxt, 1);
}
} s = n + 1, t = n + 2; for (int i = 1; i <= n; i++)
if (col[i] == 0)
add(s, i, 1);
else
add(i, t, 1); while (bfs() == true)
maxflow += dinic(s, inf); for (int i = 1; i <= n + 2; i++) {
if (use[i] == 0)
tanjan(i);
} for (int i = 1; i <= n; i++) {
for (int nxt : Road[i]) {
if (e[f[i][nxt]].w == 0 && color[i] != color[nxt]) {
chifan.insert(make_pair(min(i, nxt), max(i, nxt)));
}
}
} cout << chifan.size() << '\n'; for (pair<int, int> OUT : chifan) {
cout << OUT.first << ' ' << OUT.second << '\n';
}
}

P3731 题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

  10. JSOI2016R3 瞎BB题解

    题意请看absi大爷的blog http://absi2011.is-programmer.com/posts/200920.html http://absi2011.is-programmer.co ...

随机推荐

  1. (更新中)Python、JavaScript、Java和C++语言的语法对比与梳理

    目录 引言 1. 构造函数 Python JavaScript Java C++ 2. 构造类 Python JavaScript Java C++ 3. 总结 引言 在开发过程中不免需要用到多种编程 ...

  2. 如何在Ubuntu 20.04上安装Pyenv 管理多版本Python

    目录 ubuntu安装pyenv 管理多版本Python 参考文档: 安装pyenv: pyenv 命令列表 pycharm配置 ubuntu安装pyenv 管理多版本Python 参考文档: htt ...

  3. Java工具类库大总结

    1. Java自带工具方法 1.1 List集合拼接成以逗号分隔的字符串 // 如何把list集合拼接成以逗号分隔的字符串 a,b,c List<String> list = Arrays ...

  4. Splashtop :符合 HIPAA 标准的远程桌面软件

    如果您正在寻找可帮助您保持 HIPAA 遵从性的远程桌面软件,那么 Splashtop 就是您的最佳选择. 如果您的公司属于美国医疗保健行业,则您知道您必须遵守有关敏感和私人患者信息的联邦 HIPAA ...

  5. 在 Chromebook 上使用 Word 的最佳方法

    Splashtop 允许您从 Chromebook 远程控制 Windows 和 Mac 计算机,从而可以访问 Word 的桌面版本和所有文件. 对于远程工作者和学生,Chromebook 可以是一种 ...

  6. 物联网平台在AIoT领域8大场景应用

    物联网平台技术在AIoT智慧物联领域的应用越来越深入,尤其是在智慧城市建设项目中,提供了强有力的技术底座工具支撑.ToG的项目需要"门当户对"的服务商具备完善的资质和靠谱的技术服务 ...

  7. 2024-05-18:用go语言,给定一个从 0 开始的字符串 s,以及两个子字符串 a 和 b,还有一个整数 k。 定义一个“美丽下标”,当满足以下条件时: 1.找到字符串 a 在字符串 s 中的位

    2024-05-18:用go语言,给定一个从 0 开始的字符串 s,以及两个子字符串 a 和 b,还有一个整数 k. 定义一个"美丽下标",当满足以下条件时: 1.找到字符串 a ...

  8. centos7源码编译安装nginx1.19并调优,向已安装的nginx添加新模块

    目录 一.关于nginx 二.nginx的安装方式 三.源码编译安装nginx 3.1 下载nginx源码并解压 3.2 创建nginx用户和组 3.3 安装nginx编译环境(解决依赖问题) 3.4 ...

  9. Maven到底是什么

    Maven 是一个项目管理工具,它最主要的两个功能就是:依赖管理和项目构建. 何为依赖管理 ​ 在传统项目中,我们的项目如果需要第三方提供的库就必须得去官网上下载,有了Maven我们只需要在pom文件 ...

  10. docker基础使用和资源限制

    为什么使用容器 docker设计目标: 提供简单的应用打包工具 开发人员和运维人员职责逻辑分离 多环境保持一致性 轻量级 kubernetes设计目标: 集中管理所有容器 资源编排 资源调度 弹性伸缩 ...