BZOJ 2229 最小割
2024-08-24 22:23:22
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=2229
题意:给定一个带权无向图。若干询问,每个询问回答有多少点对(s,t)满足s和t的最小割小于等于x。
思路:对于两个点(s,t)的最小割。这个最小割将将所有点分成左右两个集合X、Y。对于X中任意一点a与Y中任意一点b,(a,b)的最小割小于等于(s,t)的最小割。因此,每次递归计算分成的两个集合的最小割,更新答案。
struct node { int v,cap,next; }; node edges[N*N*10]; int head[N],e; void add(int u,int v,int cap) { edges[e].v=v; edges[e].cap=cap; edges[e].next=head[u]; head[u]=e++; } void Add(int u,int v,int cap) { add(u,v,cap); add(v,u,0); } int pre[N],cur[N],num[N],h[N]; int Maxflow(int s,int t,int n) { int i; for(i=0;i<=n;i++) cur[i]=head[i],num[i]=h[i]=0; int u=s,Min,k,v; int ans=0; while(h[u]<n) { if(u==t) { Min=INF; for(i=s;i!=t;i=edges[cur[i]].v) { k=cur[i]; if(edges[k].cap<Min) Min=edges[k].cap,v=i; } ans+=Min; u=v; for(i=s;i!=t;i=edges[cur[i]].v) { k=cur[i]; edges[k].cap-=Min; edges[k^1].cap+=Min; } } for(i=cur[u];i!=-1;i=edges[i].next) { if(edges[i].cap>0&&h[u]==h[edges[i].v]+1) break; } if(i!=-1) { cur[u]=i; pre[edges[i].v]=u; u=edges[i].v; } else { if(--num[h[u]]==0) break; k=n; cur[u]=head[u]; for(i=head[u];i!=-1;i=edges[i].next) { if(edges[i].cap>0&&h[edges[i].v]<k) { k=h[edges[i].v]; } } num[k+1]++; h[u]=k+1; if(u!=s) u=pre[u]; } } return ans; } int List[N][N],a[N][N],p[N][N]; int n,m; int MinCut[N][N]; int b[N]; void build(int s,int t) { clr(head,-1); e=0; int i,j,u,v; FOR1(i,n) { u=i; for(j=1;j<=List[u][0];j++) { v=List[u][j]; if(u!=t&&v!=s) Add(u,v,a[u][v]); } } } int visit[N]; void DFS(int u) { visit[u]=1; int i,v; for(i=head[u];i!=-1;i=edges[i].next) { v=edges[i].v; if(edges[i].cap>0&&!visit[v]) DFS(v); } } void DFS(int L,int R) { if(L==R) return; int s=b[L],t=b[R]; build(s,t); int temp=Maxflow(s,t,n); clr(visit,0); DFS(s); int i,j,u,v,X[N],Y[N],xNum=0,yNum=0; for(i=L;i<=R;i++) { if(visit[b[i]]) X[++xNum]=b[i]; else Y[++yNum]=b[i]; } FOR1(i,n) if(visit[i]) FOR1(j,n) if(!visit[j]) { u=i; v=j; MinCut[u][v]=MinCut[v][u]=min(MinCut[u][v],temp); } FOR1(i,xNum) b[L+i-1]=X[i]; FOR1(j,yNum) b[L+xNum+j-1]=Y[j]; DFS(L,L+xNum-1); DFS(L+xNum,R); } int main() { rush() { RD(n,m); int i,j,u,v,w; FOR1(i,n) List[i][0]=0; clr(a,0); clr(p,0); FOR1(i,m) { RD(u,v,w); if(!p[u][v]) { List[u][++List[u][0]]=v; List[v][++List[v][0]]=u; p[u][v]=p[v][u]=1; } a[u][v]+=w; a[v][u]+=w; } FOR1(i,n) b[i]=i; FOR1(i,n) FOR1(j,n) MinCut[i][j]=INF; DFS(1,n); int Q,x,ans; RD(Q); while(Q--) { RD(x); ans=0; FOR1(i,n) for(j=i+1;j<=n;j++) if(MinCut[i][j]<=x) ans++; PR(ans); } puts(""); } }
最新文章
- C#常用类库(100多个)
- 摘抄转载前辈们的Java集合类总结
- 拷贝数据库和VS项目
- UVA 1001 Say Cheese 奶酪里的老鼠(最短路,floyd)
- amazon RequestReport
- jS判断浏览器终端
- BZOJ_4448_[Scoi2015]情报传递_主席树
- MySQL性能优化总结___本文乃《MySQL性能调优与架构设计》读书笔记!
- anaconda3下64位python和32位python共存
- NetworkStream介绍说明
- mybatis批量更新报错badsql
- 关于TensorFlow你需要了解的9件事
- BZOJ5300 [Cqoi2018]九连环 【数学】【FFT】
- 5+ App开发打包指南
- HDU 1716:排列2(全排列)
- ES6中的Promise使用方法与总结
- SQL语句关联查询
- 【纪中集训2019.3.27】【集训队互测2018】小A的旅行(白)
- Android性能优化工具之Systrace
- SpringBoot(三)-- 整合FreeMarker模板
热门文章
- (转) 关于Oracle EBS邮件服务无法使用的报错
- RC-50221 问题解决 - netstat 查看端口占用情况
- 夺命雷公狗—angularjs—15—内置封装好的计时器$interval和$timeout
- 夺命雷公狗---DEDECMS----9dedecms单标签
- Imageloarder
- python实现指定目录下批量文件的单词计数:串行版本
- 常用Git命令
- Linux中变量#,#,@,0,0,1,2,2,*,$$,$?的含义【转】
- 设置 textarea 默认滑动到底部
- [转]如何:在设备上安装 SQL Server Compact 3.5