小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点\(s,t\)不在同一个部分中,则称这个划分是关于\(s,t\)的割。 对于带权图来说,将所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而\(s,t\)的最小割指的是在关于\(s,t\)的割中容量最小的割” 现给定一张无向图,小白有若干个形如“图中有多少对点它们的最小割的容量不超过\(x\)呢”的疑问,小蓝虽然很想回答这些问题,但小蓝最近忙着挖木块,于是作为仍然是小蓝的好友,你又有任务了。

Input

输入文件第一行有且只有一个正整数T,表示测试数据的组数。 对于每组测试数据, 第一行包含两个整数\(n,m\),表示图的点数和边数。 下面\(m\)行,每行3个正整数\(u,v,c(1<=u,v<=n,0<=c<=10^6)\),表示有一条权为\(c\)的无向边\((u,v)\) 接下来一行,包含一个整数\(q\),表示询问的个数 下面\(q\)行,每行一个整数\(x\),其含义同题目描述。

Output

对于每组测试数据,输出应包括\(q\)行,第\(i\)行表示第\(i\)个问题的答案。对于点对\((p,q)\)和\((q,p)\),只统计一次(见样例)。

两组测试数据之间用空行隔开。

Sample Input

1
5 0
1
0

Sample Output

10

Hint

对于100%的数据 \(T<=10,n<=150,m<=3000,q<=30\),\(x\)在32位有符号整数类型范围内。

图中两个点之间可能有多条边

题意:

中文题面,不解释

题解:

最小割树求出所有的最小割,放入一个数组里面,然后对于么一个询问二分就行了。

有一个坑点,就是每组数据处理完之后要额外输出一个空行。

#include<bits/stdc++.h>
#define re register
using namespace std;
const int N=300,M=10010;
const long long inf=1ll<<60;
int n,m,a[N];
long long ans[N][N];
int head[N],nxt[M],bian[M];
long long zhi[M];
int tot;
void init(){
tot=1;
memset(head,0,sizeof head);
}
void add(int x,int y,long long z){
tot++;bian[tot]=y;zhi[tot]=z;nxt[tot]=head[x];head[x]=tot;
tot++;bian[tot]=x;zhi[tot]=z;nxt[tot]=head[y];head[y]=tot;
}
void build(int m){
for(int i=1;i<=m;i++){
int x,y;
long long z;
scanf("%d%d%lld",&x,&y,&z);
add(x,y,z);
}
}
void rebuild(){
for(int i=1;i<=tot;i+=2){
zhi[i]=zhi[i^1]=(zhi[i]+zhi[i^1])/2;
}
}
int v[N];
void cut(int x){
v[x]=1;
for(int i=head[x];i;i=nxt[i]){
if(zhi[i]&&!v[bian[i]])cut(bian[i]);
}
}
int d[N];
queue<int>q;
bool bfs(int b,int e){
memset(d,0,sizeof(d));
while(!q.empty())q.pop();
q.push(b);d[b]=1;
while(!q.empty()){
int x=q.front();q.pop();
for(int i=head[x];i;i=nxt[i]){
if(zhi[i] && !d[bian[i]]){
q.push(bian[i]);
d[bian[i]]=d[x]+1;
if(bian[i]==e)return 1;
}
}
}
return 0;
}
long long dinic(int b,int e,int x,long long flow){
if(x==e)return flow;
long long rest=flow,k;
for(int i=head[x];i && rest;i=nxt[i]){
if(zhi[i] && d[bian[i]]==d[x]+1){
k=dinic(b,e,bian[i],min(rest,zhi[i]));
if(!k)d[bian[i]]=0;
zhi[i]-=k;
zhi[i^1]+=k;
rest-=k;
}
}
return flow-rest;
}
inline long long maxflow(int b,int e){
long long flow=0,maxflow=0;
while(bfs(b,e)){
while(flow=dinic(b,e,b,inf))maxflow+=flow;
}
return maxflow;
}
int b,e;
void solve(int l,int r){
if(l==r)return;
rebuild();
b=a[l],e=a[r];
re long long mincut=maxflow(b,e);
memset(v,0,sizeof v);
cut(b);
for(re int i=1;i<=n;++i){
if(!v[i])continue;
for(re int j=1;j<=n;++j){
if(v[j])continue;
ans[i][j]=ans[j][i]=min(ans[i][j],mincut);
}
}
re int cnt=l-1;
static int ls[N];
for(re int i=l;i<=r;++i){
if(v[a[i]]){
ls[++cnt]=a[i];
}
}
re int fj=cnt;
for(re int i=l;i<=r;++i){
if(!v[a[i]]){
ls[++cnt]=a[i];
}
}
for(re int i=l;i<=r;++i)a[i]=ls[i];
solve(l,fj);
solve(fj+1,r);
}
int main()
{
int b,e,Q,T;
cin>>T;
while(T--){
memset(ans,0x3f3f3f,sizeof ans);
scanf("%d%d",&n,&m);
init();
build(m);
for(int i=1;i<=n;++i){
a[i]=i;
}
solve(1,n);
scanf("%d",&Q);
static long long as[40010];
int js=0;
for(int i=1;i<=n;++i){
for(int j=i+1;j<=n;++j){
as[++js]=ans[i][j];
}
}
sort(as+1,as+js+1);
long long ask;
for(int i=1;i<=Q;++i){
scanf("%lld",&ask);
int mid=lower_bound(as,as+js+1,ask+1)-as;
while(mid>js||(as[mid]>ask&&mid))mid--;
printf("%d\n",mid);
}puts("");
}
}

最小割(zjoi2011,bzoj2229)(最小割树)的更多相关文章

  1. [ZJOI2011][bzoj2229] 最小割 [最小割树]

    题面 传送门 思路 首先我们明确一点:这道题不是让你把$n^2$个最小割跑一遍[废话] 但是最小割过程是必要的,因为最小割并没有别的效率更高的算法(Stoer-Wagner之类的?) 那我们就要尽量找 ...

  2. 【BZOJ2229】【ZJOI2011】最小割

    冷门知识点…… 原题: 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中 ...

  3. 【bzoj2229】[Zjoi2011]最小割 分治+网络流最小割

    题目描述 小白在图论课上学到了一个新的概念——最小割,下课后小白在笔记本上写下了如下这段话: “对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分 ...

  4. 「ZJOI2011」最小割

    「ZJOI2011」最小割 传送门 建出最小割树,然后暴力计算任意两点之间最小割即可. 多组数据记得初始化. 参考代码: #include <algorithm> #include < ...

  5. bzoj 2229 [Zjoi2011]最小割(分治+最小割)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2229 [题意] 回答若干个关于割不超过x的点对数目的询问. [思路] [最小割最多有n ...

  6. 不同的最小割(cqoi2016,bzoj4519)(最小割树)

    学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成 两个部分,如果结点\(s,t\)不在同一个部分中,则称这个划分是关于\(s,t\)的割.对于带权图来说,将 所有顶 ...

  7. bzoj 1797: [Ahoi2009]Mincut 最小割【tarjan+最小割】

    先跑一遍最大流,然后对残量网络(即所有没有满流的边)进行tarjan缩点. 能成为最小割的边一定满流:因为最小割不可能割一半的边: 连接s.t所在联通块的满流边一定在最小割里:如果不割掉这条边的话,就 ...

  8. Destroying The Graph 最小点权集--最小割--最大流

    Destroying The Graph 构图思路: 1.将所有顶点v拆成两个点, v1,v2 2.源点S与v1连边,容量为 W- 3.v2与汇点连边,容量为 W+ 4.对图中原边( a, b ), ...

  9. 【poj3522-苗条树】最大边与最小边差值最小的生成树,并查集

    题意:求最大边与最小边差值最小的生成树.n<=100,m<=n*(n-1)/2,没有重边和自环. 题解: m^2的做法就不说了. 时间复杂度O(n*m)的做法: 按边排序,枚举当前最大的边 ...

随机推荐

  1. web API分类

    什么是Web API? Web API是网络应用程序接口.包含了广泛的功能,网络应用通过API接口,可以实现存储服务.消息服务.计算服务等能力,利用这些能力可以进行开发出强大功能的web应用. 分类 ...

  2. QualNet/EXata的发展贯穿在美军网络中心战演进的始终

    QualNet/EXata的发展贯穿在美军网络中心战演进的始终 赵玉亭 1.   QualNet/EXata的前身GloMoSim是美国防部高级计划研究局(DARPA)在1994年启动的全球移动信息系 ...

  3. /bin/sh^M:bad interpreter:

    /bin/sh^M:bad interpreter: No such file or directory 这个错误发生在你在windows下编写文件上传到linux服务器去运行的时候. 错误原因:wi ...

  4. Anaconda 3中配置OpenCV

    平台:win10 x64+Anaconda 3(64-bit)+opencv_python-3.4.5+contrib-cp37-cp37m-win_amd64 一.OpenCV下载 Python环境 ...

  5. 2019.01.20 bzoj2388: 旅行规划(分块+凸包)

    传送门 分块好题. 题意:维护区间加,维护区间前缀和的最大值(前缀和指从1开始的). 思路: 考虑分块维护答案. 我们把每个点看成(i,sumi)(i,sum_i)(i,sumi​)答案一定会在凸包上 ...

  6. mac os 下 Android Studio设置真机调试

    http://www.cnblogs.com/developer-wang/p/6719555.html 如果没有 .bash_profile 只需要创建 .bash_profile,然后增加andr ...

  7. Linux主机名域名修改问题

    1.修改 /etc/sysconfig/network  配置文件 vi  /etc/sysconfig/network 修改HOSTNAMEHOSTNAME=new-hostname.domainn ...

  8. 20155205《Java程序设计》实验五(网络编程与安全)实验报告

    20155205 <Java程序设计>实验五(网络编程与安全)实验报告 一.实验内容及步骤 (一) 两人一组结对编程 参考http://www.cnblogs.com/rocedu/p/6 ...

  9. 1101 Quick Sort

    There is a classical process named partition in the famous quick sort algorithm. In this process we ...

  10. MIT Molecular Biology 笔记5 转录机制

    视频  https://www.bilibili.com/video/av7973580?from=search&seid=16993146754254492690 教材 Molecular ...