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

题面

洛谷

给定一张反图,保证原图能分成不超过两个团,问有多少种加上一条边的方法,使得最大团的个数至少加上\(1\)。

题解

本来并不会做的,看题解第一句话就会了QwQ

对于在反图上没有边的点之间是存在一条边的。

那么考虑原图的一个团对应在反图上是什么,因为原图的团内的点两两之间有边,所以对应在反图上两两之间无边。所以原图的一个团对应着反图的一个独立集。

因为原图可以分解为不超过\(2\)个团,所以反图可以分解成一个二分图。

于是问题变成了,删去反图上的哪条边,可以让反图的最大独立集变大。

二分图最大独立集=总点数-最小点覆盖,而最小点覆盖=二分图最大匹配。

于是问题变成了哪些边必定出现在二分图的最大匹配中。

那么先跑\(Dinic\)之后用\(Tarjan\)把残余网络缩点,

必定在二分图匹配上的边就是那些满流并且连接的两点不在同一个\(scc\)内的边。

证明大概就是如果两者在同一个\(scc\)内,那么必定存在另外一条匹配边可以替换这条边。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define MAXN 10100
#define MAXM 150150
#define inf 1e9
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
struct Line{int v,next,w;}e[MAXM<<1];
int h[MAXN],cnt=2;
inline void Add(int u,int v,int w)
{
e[cnt]=(Line){v,h[u],w};h[u]=cnt++;
e[cnt]=(Line){u,h[v],0};h[v]=cnt++;
}
int S,T,level[MAXN];
bool bfs()
{
for(int i=S;i<=T;++i)level[i]=0;
queue<int> Q;level[S]=1;Q.push(S);
while(!Q.empty())
{
int u=Q.front();Q.pop();
for(int i=h[u];i;i=e[i].next)
if(e[i].w&&!level[e[i].v])
level[e[i].v]=level[u]+1,Q.push(e[i].v);
}
return level[T];
}
int cur[MAXN];
int dfs(int u,int flow)
{
if(u==T||!flow)return flow;
int ret=0;
for(int &i=cur[u];i;i=e[i].next)
{
int v=e[i].v,d;
if(e[i].w&&level[v]==level[u]+1)
{
d=dfs(v,min(flow,e[i].w));
ret+=d;flow-=d;
e[i].w-=d;e[i^1].w+=d;
if(!flow)break;
}
}
if(!ret)level[u]=0;
return ret;
}
int Dinic()
{
int ret=0;
while(bfs())
{
for(int i=S;i<=T;++i)cur[i]=h[i];
ret+=dfs(S,inf);
}
return ret;
}
vector<pair<int,int> > Ans;
vector<int> E[MAXN];
int n,m,col[MAXN];
void pre(int u,int c){col[u]=c;for(int v:E[u])if(!col[v])pre(v,c^1);}
int dfn[MAXN],low[MAXN],tim,G[MAXN],gr;
int St[MAXN],top;bool ins[MAXN];
void Tarjan(int u)
{
dfn[u]=low[u]=++tim;St[++top]=u;ins[u]=true;
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(!e[i].w)continue;
if(!dfn[v])Tarjan(v),low[u]=min(low[u],low[v]);
else if(ins[v])low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
++gr;int v;
do{v=St[top--];G[v]=gr;ins[v]=false;}while(u!=v);
}
}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
E[u].push_back(v);
E[v].push_back(u);
}
for(int i=1;i<=n;++i)if(!col[i])pre(i,2);
S=0;T=n+1;
for(int i=1;i<=n;++i)
if(col[i]==2)
{
Add(S,i,1);
for(int v:E[i])Add(i,v,1);
}
else Add(i,T,1);
int ret=Dinic();
for(int i=S;i<=T;++i)if(!dfn[i])Tarjan(i);
for(int u=1;u<=n;++u)
if(col[u]==2)
for(int i=h[u];i;i=e[i].next)
{
int v=e[i].v;if(e[i].w)continue;
if(v==S||v==T)continue;
if(G[u]!=G[v])Ans.push_back(u<v?make_pair(u,v):make_pair(v,u));
}
sort(Ans.begin(),Ans.end());
printf("%d\n",(int)Ans.size());
for(auto a:Ans)printf("%d %d\n",a.first,a.second);
return 0;
}

【Luogu3731】[HAOI2017]新型城市化(网络流,Tarjan)的更多相关文章

  1. P3731 [HAOI2017]新型城市化(tarjan+网络流)

    洛谷 题意: 给出两个最大团的补图,现在要求增加一条边,使得最大最大团个数增加至少\(1\). 思路: 我们求出团的补图,问题可以转换为:对于一个二分图,选择删掉一条边,能够增大其最大独立集的点集数. ...

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

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

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

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

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

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

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

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

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

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

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

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

  8. [HAOI2017] 新型城市化

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

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

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

随机推荐

  1. HDU 2001 计算两点间的距离

    http://acm.hdu.edu.cn/showproblem.php?pid=2001 Problem Description 输入两点坐标(X1,Y1),(X2,Y2),计算并输出两点间的距离 ...

  2. Jenkins [Error] at org.codehaus.cargo.container.tomcat.internal.AbstractTomcatManagerDeployer.redeploy(AbstractTomcatManagerDeployer.java:192)

    Deploying /root/.jenkins/workspace/zgg-crm-pre/target/crm.war to container Tomcat 7.x Remote with co ...

  3. JS 验证输入框输入 只允许输入正实数(正整数,正小数),其他情况下不能输入 oninput事件

    input标签的oninput事件 要求输入框只输入正实数,包括整数和小数. 具体要求:整数部分不超过7位,可以没有小数,若有位数不超过2位. <input type="text&qu ...

  4. JS 获取链接中的参数

    1.获取链接全部参数,以对象的形式返回 //获取url中参数 function GetRequest() { var url = location.search; //获取url中"?&qu ...

  5. 配置SQLServer,允许远程连接

    需要别人远程你的数据库,首先需要的是在一个局域网内,或者连接的是同一个路由器,接下来就是具体步骤: (一)首先是要检查SQLServer数据库服务器中是否允许远程链接.其具体操作为: (1)打开数据库 ...

  6. Java中的break,continue关于标签的用法(转载)

    Java的控制循环结构中是没有关键字goto的,这种做法有它的好处,它提高了程序流程控制的可读性,但是也有不好的地方,它降低了程序流程控制的灵活性,所以说,“上帝是公平的”.所以,Java为了弥补这方 ...

  7. K8S集群 NOT READY的解决办法 1.13 错误信息:cni config uninitialized

    今天给同事 一个k8s 集群 出现not ready了 花了 40min 才搞定 这里记录一下 避免下载 再遇到了 不清楚. 错误现象:untime network not ready: Networ ...

  8. [转帖]SUSE Linux

    历经坎坷多次易主,SUSE Linux路在何方? http://blog.itpub.net/11310314/viewspace-2638811/ 之前一直理不清楚 SUSE和RedHat的关系 甚 ...

  9. easyUI定区关联快递员js代码

    easyUI定区关联快递员js代码: <script type="text/javascript"> $.fn.serializeJson=function(){ va ...

  10. Spring boot 将配置文件属性注入到一个bean中

    现在要做的就是将如下配置文件中的内容注入到一个bean 名为Properties中. Redis.properties配置文件中的内容如下: Properties java bean中代码如下,注意注 ...