洛谷

题意:

给出两个最大团的补图,现在要求增加一条边,使得最大最大团个数增加至少\(1\)。

思路:

  • 我们求出团的补图,问题可以转换为:对于一个二分图,选择删掉一条边,能够增大其最大独立集的点集数。
  • 然后做法就是考虑在最大流的残余网络上,对容量为\(1\)的边求强连通分量(包含源点、汇点)。
  • 若存在一条边\((x,y)\)为匹配边,并且\(x,y\)在不同的强连通分量中,那么\((x,y)\)这条边为必经边,即最大匹配中包含这条边;若\((x,y)\)为非匹配边并且\(x,y\)在同一强连通分量中,那么\((x,y)\)为最大匹配的可行边,即这条边存在于至少一个最大匹配中。
  • 证明的话,就拿必经边来说,若\((x,y)\)在同一强连通分量中,我们去掉\(x,y\)这条边,还是有增广路径能从\(x\)到\(y\),此时最大匹配没变并且\((x,y)\)流量为\(0\)。所以\((x,y)\)不能在同一强连通分量中。

注意一开始要对图进行二分图染色。

代码如下:

#include <bits/stdc++.h>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 5e4 + 5, M = 1e6 + 5; #define INF 0x3f3f3f3f
template <class T>
struct Dinic{
struct Edge{
int v, next;
T flow;
Edge(){}
Edge(int v, int next, T flow) : v(v), next(next), flow(flow) {}
}e[M << 1];
int head[N], tot;
int dep[N];
void init() {
memset(head, -1, sizeof(head)); tot = 0;
}
void adde(int u, int v, T w, T rw = 0) {
e[tot] = Edge(v, head[u], w);
head[u] = tot++;
e[tot] = Edge(u, head[v], rw);
head[v] = tot++;
}
bool BFS(int _S, int _T) {
memset(dep, 0, sizeof(dep));
queue <int> q; q.push(_S); dep[_S] = 1;
while(!q.empty()) {
int u = q.front(); q.pop();
for(int i = head[u]; ~i; i = e[i].next) {
int v = e[i].v;
if(!dep[v] && e[i].flow > 0) {
dep[v] = dep[u] + 1;
q.push(v);
}
}
}
return dep[_T] != 0;
}
T dfs(int _S, int _T, T a) {
T flow = 0, f;
if(_S == _T || a == 0) return a;
for(int i = head[_S]; ~i; i = e[i].next) {
int v = e[i].v;
if(dep[v] != dep[_S] + 1) continue;
f = dfs(v, _T, min(a, e[i].flow));
if(f) {
e[i].flow -= f;
e[i ^ 1].flow += f;
flow += f;
a -= f;
if(a == 0) break;
}
}
if(!flow) dep[_S] = -1;
return flow;
}
T dinic(int _S, int _T) {
T max_flow = 0;
while(BFS(_S, _T)) max_flow += dfs(_S, _T, INF);
return max_flow;
}
stack <int> s;
int dfs_T, num;
int scc[N], dfn[N], low[N];
void Tarjan(int u){
dfn[u] = low[u] = ++dfs_T;
s.push(u);
for(int i = head[u]; i != -1;i = e[i].next){
int v = e[i].v;
if(e[i].flow == 0) continue;
if(!dfn[v]){
Tarjan(v);
low[u] = min(low[u], low[v]);
}else if(!scc[v]){
low[u] = min(low[u], dfn[v]);
}
}
if(low[u] == dfn[u]){
num++; int now;
do{
now = s.top(); s.pop();
scc[now] = num;
}while(!s.empty() && now!=u);
}
}
};
Dinic <int> solve; int n, m; vector <int> g[N];
int col[N];
void color(int u, int c) {
col[u] = c;
for(auto v : g[u]) {
if(!col[v]) color(v, 3 - c);
}
} void run() {
solve.init();
for(int i = 1; i <= m; i++) {
int u, v; cin >> u >> v;
g[u].push_back(v);
g[v].push_back(u);
}
for(int i = 1; i <= n; i++) {
if(!col[i]) color(i, 1);
}
int t = 2 * n + 1;
for(int i = 1; i <= n; i++) {
if(col[i] == 1) {
solve.adde(0, i, 1);
for(auto j : g[i]) {
solve.adde(i, j + n, 1);
}
} else {
solve.adde(i + n, t, 1);
}
}
int flow = solve.dinic(0, t);
dbg(flow);
for(int i = 0; i <= t; i++) {
if(!solve.dfn[i]) {
solve.Tarjan(i);
}
}
dbg(solve.num);
vector <pii> ans;
for(int u = 1; u <= n; u++) {
for(int i = solve.head[u]; i != -1; i = solve.e[i].next) {
int v = solve.e[i].v;
if(solve.e[i].flow == 1) continue;
if(v > n && solve.scc[u] != solve.scc[v]) {
int x = u, y = v - n;
if(x > y) swap(x, y);
ans.push_back(MP(x, y));
}
}
}
sort(all(ans), [&](pii A, pii B) {
if(A.fi == B.fi) return A.se < B.se;
return A.fi < B.fi;
});
pt(sz(ans));
for(auto it : ans) cout << it.fi << ' ' << it.se << '\n';
} int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
#ifdef Local
freopen("../input.in", "r", stdin);
freopen("../output.out", "w", stdout);
#endif
while(cin >> n >> m) run();
return 0;
}

P3731 [HAOI2017]新型城市化(tarjan+网络流)的更多相关文章

  1. 【Luogu3731】[HAOI2017]新型城市化(网络流,Tarjan)

    [Luogu3731][HAOI2017]新型城市化(网络流,Tarjan) 题面 洛谷 给定一张反图,保证原图能分成不超过两个团,问有多少种加上一条边的方法,使得最大团的个数至少加上\(1\). 题 ...

  2. 洛谷 P3731 [HAOI2017]新型城市化【最大流(二分图匹配)+tarjan】

    我到底怎么建的图为啥要开这么大的数组啊?! 神题神题,本来以为图论出不出什么花来了. 首先要理解'团'的概念,简单来说就是无向图的一个完全子图,相关概念详见度娘. 所以关于团一般都是NP问题,只有二分 ...

  3. Luogu P3731 [HAOI2017]新型城市化

    题目显然可以转化为求每一条边对二分图最大独立集的贡献,二分图最大独立集\(=\)点数\(-\)最大匹配数,我们就有了\(50pts\)做法. 正解的做法是在原图上跑\(Tarjan\),最开始我想复杂 ...

  4. 求去掉一条边使最小割变小 HAOI2017 新型城市化

    先求最小割,然后对残量网络跑Tarjan.对于所有满流的边,若其两端点不在同一个SCC中,则这条边是满足条件的. 证明见 来源:HAOI2017 新型城市化

  5. LOJ2276 [HAOI2017] 新型城市化 【二分图匹配】【tarjan】

    题目分析: 这题出的好! 首先问题肯定是二分图的最大独立集,如果删去某条匹配边之后独立集是否会变大. 跑出最大流之后流满的边就是匹配边. 如果一个匹配边的两个端点在一个强连通分量里,那这条边删掉之后我 ...

  6. HAOI2017 新型城市化 二分图的最大独立集+最大流+强连通缩点

    题目链接(洛谷):https://www.luogu.org/problemnew/show/P3731 题意概述:给出一张二分图,询问删掉哪些边之后可以使这张二分图的最大独立集变大.N<=10 ...

  7. Luogu3731 HAOI2017新型城市化(二分图匹配+强连通分量)

    将未建立贸易关系看成连一条边,那么这显然是个二分图.最大城市群即最大独立集,也即n-最大匹配.现在要求的就是删哪些边会使最大匹配减少,也即求哪些边一定在最大匹配中. 首先范围有点大,当然是跑个dini ...

  8. [HAOI2017] 新型城市化

    给出的图中恰包含2个团,则图的补图为一个二分图,其最大独立集为原图的最大团. 我们知道,二分图的最大独立集=V-最小顶点覆盖,最小顶点覆盖=最大匹配. 问题转化为:计算删去后最大匹配减小的边集. 所以 ...

  9. 【题解】新型城市化 HAOI2017 网络流 二分图最大匹配 强连通分量

    Prelude 好,HAOI2017终于会做一道题了! 传送到洛谷:→_→ 传送到LOJ:←_← 本篇博客链接:(●'◡'●) Solution 首先要读懂题. 考场上我是这样想的QAQ. 我们把每个 ...

随机推荐

  1. /usr/lib/python2.7/subprocess.py", line 1239, in _execute_child

    Traceback (most recent call last):File "/home/eping/bin/repo", line 685, in main(sys.argv[ ...

  2. IEEE754 浮点数

    IEEE754 浮点数 1.阅读IEEE754浮点数 A,阶码是用移码表示的,这里会有一个127的偏移量,它的127相当于0,小于127时为负,大于127时为正,比如:10000001表示指数为129 ...

  3. Educational Codeforces Round 78 (Rated for Div. 2) --补题

    链接 直接用数组记录每个字母的个数即可 #include<bits/stdc++.h> using namespace std; int a[26] = {0}; int b[26] = ...

  4. 《高性能MySQL》读后感——聚簇索引

    <高性能MySQL>读后感——聚簇索引 聚簇索引并不是一种单独的索引类型,而是一种数据存储方式.比如,InnoDB的聚簇索引使用B+Tree的数据结构存储索引和数据. 当表有聚簇索引时,它 ...

  5. html行级元素与块级元素以及meta标签的使用

    块级元素的特性: 永远都会占满父级元素的宽度(块级元素的宽度永远都等于它父级元素的宽度) 行级元素的特性: 所占的空间刚好等于内容的大小 常见的块级元素: h1~h6.p.ul.div.li.form ...

  6. 一种单机支持 JavaWeb 容器万级并发的设想

    当前的大部分 Java web 容器基于 Bio 线程模型,例如常见的 tomcat ,默认 200 线程,即 200 连接.由此带来的问题是,如果想提高并发,或者提高资源利用率,就得加大线程数. 如 ...

  7. Pandownload倒下了,还有它,又一款百度云下载神器,速度可达10M/s

    最近很多小伙伴反馈 Pandownload 不好使了 对此我表示 脑壳疼 不过经过一番折腾 还是找到了一个不错的替代品 它就是 baidupcs-web 下载解压后就这么一个可执行文件 干净的不可思议 ...

  8. 周董新歌搞崩QQ,抓取20W评论看看歌迷在说啥

    9 月 16 日晚间,周董在朋友圈发布了最新单曲<说好不哭> 发布后,真的让一波人哭了 一群想抢鲜听的小伙伴直接泪奔 因为 QQ 音乐直接被搞崩了 没想到干翻 QQ 音乐的不是网易云音乐 ...

  9. 九、Spring之BeanFactory源码分析(一)

    Spring之BeanFactory源码分析(一) ​ 注意:该随笔内容完全引自https://blog.csdn.net/u014634338/article/details/82865644,写的 ...

  10. Uboot启动流程分析(二)

    1.前言 在前面的文章Uboot启动流程分析(一)中,链接如下: https://www.cnblogs.com/Cqlismy/p/12000889.html 已经简单地分析了low_level_i ...