洛谷 P3731 [HAOI2017]新型城市化
2018-03-15 17:43
369 查看
题目
原题链接给定一张图,这张图最多有两个团,求增加一条边使得最大团变大。
分析
再也不乱给边加上界了啊啊啊啊!!!这张图的补图一定是二分图。
其中最大团就是最大独立集。
最大独立集就是结点数-最大流
我们要最大流减少
所以我们要找最小割
按照BZOJ 1797: [Ahoi2009]Mincut 最小割(我的博客)第一问的方法判断一个结点是否是一种最小割里面的一个点就可以了。
二分图千万反向边千万不要偷懒使得上界和正向边相同。
网络流都不要偷懒乱加上界!
代码
#include<cmath> #include<queue> #include<cctype> #include<cstdio> #include<vector> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int maxn=10000+105,maxm=15e4+105,inf=1e8; int np,first[maxn]; struct edge{ int from,to,next,cap,flow; }E[maxm<<1]; void add(int u,int v,int c) { E[++np]=(edge){u,v,first[u],c,0}; first[u]=np; } int n,m,s,t; void Init() { int u,v; np=-1; memset(first,-1,sizeof(first)); scanf("%d%d",&n,&m); s=n+1,t=s+1; for(int i=1;i<=m;i++) { scanf("%d%d",&u,&v); add(u,v,1); add(v,u,1); } } int dist[maxn],gap[maxn]; int SAP(int i,int lim) { if(i==t)return lim; int flow=0,tmp; for(int p=first[i];p!=-1;p=E[p].next)if(E[p].cap-E[p].flow) { int j=E[p].to; if(dist[i]==dist[j]+1) { tmp=SAP(j,min(lim-flow,E[p].cap-E[p].flow)); E[p].flow+=tmp; E[p^1].flow-=tmp; flow+=tmp; if(dist[s]>=t || lim==flow)return flow; } } if(flow==0) { if(--gap[dist[i]]==0)dist[s]=t; gap[++dist[i]]++; } return flow; } void maxFlow() { memset(gap,0,sizeof(gap)); memset(dist,0,sizeof(dist)); gap[0]=t; while(dist[s]<t)SAP(s,inf); } int stk[maxn],top; int dfs_clock,scc,belong[maxn],low[maxn],dfn[maxn]; void DFS(int i) { stk[++top]=i; dfn[i]=low[i]=++dfs_clock; for(int p=first[i];p!=-1;p=E[p].next) { if(E[p].cap-E[p].flow) { int j=E[p].to; if(belong[j])continue; if(dfn[j]) { low[i]=min(low[i],low[j]); continue; } DFS(j); low[i]=min(low[j],low[i]); } } if(dfn[i]==low[i]) { int x; scc++; while(1) { x=stk[top--]; belong[x]=scc; if(x==i)break; } } } void tarjian() { for(int i=1;i<=t;i++) if(!dfn[i])DFS(i); } struct data { int i,j; friend bool operator<(data a,data b) { return a.i!=b.i?a.i<b.i:a.j<b.j; } void outs() { printf("%d %d\n",i,j); } }ans[maxn]; int cnt; void query() { for(int i=1;i<=n;i++) { for(int p=first[i];p!=-1;p=E[p].next) { if(E[p].flow) { int j=E[p].to; if(j<i)continue; if(j==s || j==t)continue; if(belong[i] != belong[j]) ans[++cnt]=(data){i,j}; } } } sort(ans+1,ans+cnt+1); printf("%d\n",cnt); for(int i=1;i<=cnt;i++) ans[i].outs(); } bool vis[maxn],co[maxn]; void DFS(int i,bool c) { co[i]=c; vis[i]=1; if(c) { add(s,i,1); add(i,s,0); } else { add(i,t,1); add(t,i,0); } for(int p=first[i];p!=-1;p=E[p].next) { int j=E[p].to; if(vis[j] || j==s || j==t)continue; DFS(j,c^1); } } void erfen() { for(int i=1;i<=n;i++)if(!vis[i])DFS(i,1); for(int i=1;i<=m;i++) { int j=E[(i-1)*2].to; (!co[E[(i-1)*2].from] && co[j])?E[(i-1)*2].cap=0:E[((i-1)*2)^1].cap=0; } } int main() { //freopen("in.txt","r",stdin); Init(); erfen(); maxFlow(); tarjian(); query(); return 0; }
相关文章推荐
- 洛谷 P3731 [HAOI2017]新型城市化【最大流(二分图匹配)+tarjan】
- 【题解】新型城市化 HAOI2017 网络流 二分图最大匹配 强连通分量
- [HAOI2017]新型城市化
- luogu3731 [HAOI2017]新型城市化(二分图+网络流+tarjan求scc)
- Luogu3731 HAOI2017新型城市化(二分图匹配+强连通分量)
- 洛谷 P3732 [HAOI2017]供给侧改革【trie树】
- 洛谷3732:[HAOI2017]供给侧改革——题解
- 洛谷 P3825 游戏[NOI 2017] (2-SAT)
- ●洛谷P3687 [ZJOI2017]仙人掌
- 洛谷3707 [SDOI2017] 相关分析 【线段树】
- 洛谷 P3224 [HAOI2012]永无乡 (BZOJ 2733)
- 洛谷 P2517 [HAOI2010]订货
- 洛谷 P3773 [CTSC2017]吉夫特(bzoj P4903 [CTSC2017]吉夫特/uoj P300【CTSC2017】吉夫特)
- HAOI 2017 游记
- BZOJ1046: [HAOI2007]上升序列(洛谷P2215)
- ●洛谷P3688 [ZJOI2017]树状数组
- 洛谷P3956 [NOIp2017]棋盘
- BZOJ4889 & 洛谷3759:[TJOI2017]不勤劳的图书管理员——题解
- 洛谷3703 [SDOI2017] 树点染色 【LCT】【线段树】
- [BZOJ4889][洛谷P3759][TJOI2017]不勤劳的图书管理员 分块+树状数组