[bzoj2229][Zjoi2011]最小割_网络流_最小割树
最小割 bzoj-2229 Zjoi-2011
题目大意:题目链接。
注释:略。
想法:
在这里给出最小割树的定义。
最小割树啊,就是这样一棵树。一个图的最小割树满足这棵树上任意两点之间的最小值就是原图中这两点之间的最小割。
这个性质显然是非常优秀的。
我们不妨这样假设,我么已经把最小割树求出来了,那么这个题就迎刃而解了。
我们可以直接枚举点对,然后暴力验证就可以直接枚举出所有的合法点对是吧。
那么问题来了,我们如何才能求出所有的合法的点对?
这就需要用到了最小割树的构建过程。
我们最小割树的构建方式是分治构建的。
也就是说:
我们每次直接随意取出两个点然后在原图中求出这两个点的最小割。
并且在这两个点之间连一条等于最小割大小的边。
之后我们对于原图把所有和S相连的分到一侧,把所有和T相连的分到另一侧。
递归分治即可。
Code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#define inf 0x3f3f3f3f
#define N 155
using namespace std; int cnt,n,m,dis[N],last[N],a[N],tmp[N],ans[N][N],s,t,mark[N];
struct edge{int to,c,next;}e[N*200];
queue <int> q; void addedge(int u,int v,int c)
{
e[++cnt].to=v;e[cnt].c=c;e[cnt].next=last[u];last[u]=cnt;
e[++cnt].to=u;e[cnt].c=c;e[cnt].next=last[v];last[v]=cnt;
} bool bfs()
{
memset(dis,0,sizeof(dis));
dis[s]=2;
while (!q.empty()) q.pop();
q.push(s);
while (!q.empty())
{
int u=q.front();
q.pop();
for (int i=last[u];i;i=e[i].next)
if (e[i].c&&!dis[e[i].to])
{
dis[e[i].to]=dis[u]+1;
if (e[i].to==t) return 1;
q.push(e[i].to);
}
}
return 0;
} int dfs(int x,int maxf)
{
if (x==t||!maxf) return maxf;
int ret=0;
for (int i=last[x];i;i=e[i].next)
if (e[i].c&&dis[e[i].to]==dis[x]+1)
{
int f=dfs(e[i].to,min(e[i].c,maxf-ret));
e[i].c-=f;
e[i^1].c+=f;
ret+=f;
if (ret==maxf) break;
}
if (!ret) dis[x]=0;
return ret;
}
void dfs(int x)
{
mark[x]=1;
for (int i=last[x];i;i=e[i].next)
if (e[i].c&&!mark[e[i].to]) dfs(e[i].to);
}
void solve(int l,int r)
{
if (l==r) return;
s=a[l];t=a[r];
for (int i=2;i<=cnt;i+=2)
e[i].c=e[i^1].c=(e[i].c+e[i^1].c)/2;
int flow=0;
while (bfs()) flow+=dfs(s,inf);
memset(mark,0,sizeof(mark));
dfs(s);
for (int i=1;i<=n;i++)
if (mark[i])
for (int j=1;j<=n;j++)
if (!mark[j])
ans[i][j]=ans[j][i]=min(ans[i][j],flow);
int i=l,j=r;
for (int k=l;k<=r;k++)
if (mark[a[k]]) tmp[i++]=a[k];
else tmp[j--]=a[k];
for (int k=l;k<=r;k++)
a[k]=tmp[k];
solve(l,i-1);
solve(j+1,r);
} int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
scanf("%d%d",&n,&m);
cnt=1;
for (int i=1;i<=n;i++)
a[i]=i;
memset(last,0,sizeof(last));
memset(ans,inf,sizeof(ans));
for (int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
addedge(x,y,z);
}
solve(1,n);
int q;
scanf("%d",&q);
for (int i=1;i<=q;i++)
{
int x,tot=0;
scanf("%d",&x);
for (int i=1;i<n;i++)
for (int j=i+1;j<=n;j++)
if (ans[i][j]<=x) tot++;
printf("%d\n",tot);
}
cout<<endl;
}
return 0;
}
小结:好东西啊。
[bzoj2229][Zjoi2011]最小割_网络流_最小割树的更多相关文章
- 【BZOJ2229】[ZJOI2011]最小割(网络流,最小割树)
[BZOJ2229][ZJOI2011]最小割(网络流,最小割树) 题面 BZOJ 洛谷 题解 戳这里 那么实现过程就是任选两点跑最小割更新答案,然后把点集划分为和\(S\)联通以及与\(T\)联通. ...
- [bzoj1001][BeiJing2006]狼抓兔子_网络流_最小割转对偶图
狼抓兔子 bzoj-1001 BeiJing2006 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还 ...
- [bzoj1497][NOI2006]最大获利_网络流_最小割
最大获利 bzoj-1497 题目大意:可以建立一个点,花费一定的代价:将已经建立的两个点之间连边,得到一定收益.有些节点之间是不允许连边的. 注释:1<=点数<=5,000,1<= ...
- [bzoj2561]最小生成树_网络流_最小割_最小生成树
最小生成树 bzoj-2561 题目大意:题目链接. 注释:略. 想法: 我们发现: 如果一条权值为$L$的边想加入到最小生成树上的话,需要满足一下条件. 就是求出原图的最小生成树之后,这个边当做非树 ...
- [bzoj4519][Cqoi2016]不同的最小割_网络流_最小割_最小割树
不同的最小割 bzoj-4519 Cqoi-2016 题目大意:题目链接. 注释:略. 想法: 我们发现这和最小割那题比较像. 我们依然通过那个题说的办法一样,构建最小割树即可. 接下来就是随便怎么处 ...
- [bzoj3894]文理分科_网络流_最小割
文理分科 bzoj-3894 题目大意:题目链接. 注释:略. 想法: 这种题也是一种套路. 我们新建一个点表示收益点. 然后把所有的收益都加一起,求最小割表示代价即可. Code: #include ...
- [bzoj3630][JLOI2014]镜面通道_计算几何_网络流_最小割
镜面通道 bzoj-3630 JLOI-2014 题目大意:题目链接. 注释:略. 想法: 我们发现,只要上下界没有被完全封死,我们就一定有一条合法的光路. 所以只需要将上界和下界拆开即可. 拆点,把 ...
- [bzoj1565][NOI2009]植物大战僵尸_网络流_拓扑排序
植物大战僵尸 bzoj1565 题目大意:给你一张网格图,上面种着一些植物.你从网格的最右侧开始进攻.每个植物可以对僵尸提供能量或者消耗僵尸的能量.每个植物可以保护一个特定网格内的植物,如果一个植物被 ...
- ACM/ICPC 之 最小割转网络流(POJ3469)
重点:构图 //最小割转网络流 //邻接表+Dinic //Time:5797Ms Memory:6192K #include<iostream> #include<cstring& ...
随机推荐
- C# Equals的重写
using System; using System.Collections.Generic; using System.Text; namespace Equal { using Syste ...
- Android 轻松实现语音朗读
语音朗读,这是一个很好的功能,可以实现一些客户的特殊要求.在Android 实现主意功能只需要几段简单的代码即可完成. 在Android 中使用语音朗读功能 只需要使用此类 TextToSpeech ...
- NGUI利用深度测试实现新手引导遮罩
实现原理:实际上就是先利用渲染队列渲染,然后再利用ZTest,改变渲染的遮挡关系. PS:Depth Testing:深度测试,也叫深度缓冲.只有最靠近观察者的物体会被绘制.深度即Z,该值越小表示离观 ...
- LoadRunner10自带的WEBTOURS,无法显示Flights页面问题解决办法
[问题描述] 安装LoadRunner10之后,尝试打开自带的webTours页面学习.第一次可以打开,之后安装了一RFT.Oracle等软件,就出现页面无法显示问题.一直以为是Java的问题,尝试各 ...
- hibernate 批量插入数据
如题,有两种方法 1)使用FLUSH 2)使用JDBC 分别来解释: 1)hibernate在进行数据库操作的时候,都要有事务支持的.可能你曾遇到过,没有加事务,程序会报错的情况. 而事务每次提交的时 ...
- jsdk之微信分享流程
.步骤一:绑定域名 先登录微信公众平台进入“公众号设置”的“功能设置”里填写“JS接口安全域名”. 备注:登录后可在“开发者中心”查看对应的接口权限. .步骤二:引入JS文件 在需要调用JS接口的页面 ...
- C++学习随笔
今天试着变了下实验二里边的有关面向对象的实验,深深地觉得我对面向对象的编程的理解还是很浅显,以至于对于对象的调用也是瞎整.居然直接就去调用继承来的函数,连生成一个对象这种基础应用都不知道.对自己的基础 ...
- 1257 背包问题 V3(二分)
1257 背包问题 V3 3 秒 131,072 KB 80 分 5 级题 题意 : 从n个物品中选出k个,使单位体积价值最大 思路: 一开始正面想,试过很多种,排序什么的..总是结果不对,最后想到二 ...
- PS学习一
1.使用缩放工具时是对文档窗口进行的缩放,它只影响视图比例:而对图像的缩放则是指对图像文件本身进行的物理缩放,它会使图像的内容变大或变小. 2.分辨率是指单位长度内包含的像素点的数量,它的单位通常为像 ...
- [Python3网络爬虫开发实战] 1.2.4-GeckoDriver的安装
上一节中,我们了解了ChromeDriver的配置方法,配置完成之后便可以用Selenium驱动Chrome浏览器来做相应网页的抓取. 那么对于Firefox来说,也可以使用同样的方式完成Seleni ...