【BZOJ2229】[Zjoi2011]最小割

Description

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

Input

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

Output

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

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

Sample Input

1
5 0
1
0

Sample Output

10
【数据范围】
对于100%的数据 T<=10,n<=150,m<=3000,q<=30,x在32位有符号整数类型范围内。
图中两个点之间可能有多条边

题解:最小割树,就是利用分治,将求n^2个最小割变成求n次最小割。

我们在区间l,r中随便找两个点,求出最小割,将与S一个集合的放到左边,与T一个集合的放到右面,然后更新所有点对之间的最小割,在继续分治处理左右两边。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
int n,m,Q,S,T,cnt;
int to[10010],next[10010],val[10010],head[1000],d[300],p[300],pp[300],vis[300],map[300][300];
int s[100100];
queue<int> q;
int dfs(int x,int mf)
{
if(x==T) return mf;
int i,k,temp=mf;
for(i=head[x];i!=-1;i=next[i])
{
if(d[to[i]]==d[x]+1&&val[i])
{
k=dfs(to[i],min(temp,val[i]));
if(!k) d[to[i]]=0;
val[i]-=k,val[i^1]+=k,temp-=k;
if(!temp) break;
}
}
return mf-temp;
}
int bfs()
{
while(!q.empty()) q.pop();
memset(d,0,sizeof(d));
d[S]=1,q.push(S);
int i,u;
while(!q.empty())
{
u=q.front(),q.pop();
for(i=head[u];i!=-1;i=next[i])
{
if(!d[to[i]]&&val[i])
{
d[to[i]]=d[u]+1;
if(to[i]==T) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic()
{
int ret=0;
while(bfs()) ret+=dfs(S,1<<30);
return ret;
}
void DFS(int x)
{
vis[x]=1;
for(int i=head[x];i!=-1;i=next[i]) if(!vis[to[i]]&&val[i]) DFS(to[i]);
}
void solve(int l,int r)
{
if(l==r) return ;
S=p[l],T=p[r];
int i,j,h1=l,h2=r,mf;
for(i=0;i<cnt;i+=2) val[i]=val[i^1]=val[i]+val[i^1]>>1;
mf=dinic();
memset(vis,0,sizeof(vis));
DFS(S);
for(i=1;i<=n;i++) if(vis[i])
for(j=1;j<=n;j++) if(!vis[j])
map[i][j]=map[j][i]=min(map[i][j],mf);
for(i=l;i<=r;i++)
{
if(vis[p[i]]) pp[h1++]=p[i];
else pp[h2--]=p[i];
}
for(i=l;i<=r;i++) p[i]=pp[i];
solve(l,h2),solve(h1,r);
}
int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
void add(int a,int b,int c)
{
to[cnt]=b,val[cnt]=c,next[cnt]=head[a],head[a]=cnt++;
to[cnt]=a,val[cnt]=c,next[cnt]=head[b],head[b]=cnt++;
}
void work()
{
memset(head,-1,sizeof(head)),cnt=0;
memset(map,0x3f,sizeof(map));
n=rd(),m=rd();
int i,j,a,b,c,l,r,mid;
for(i=1;i<=n;i++) p[i]=i;
for(i=1;i<=m;i++) a=rd(),b=rd(),c=rd(),add(a,b,c);
solve(1,n);
for(s[0]=0,i=1;i<=n;i++) for(j=i+1;j<=n;j++) s[++s[0]]=map[i][j];
sort(s+1,s+s[0]+1);
Q=rd();
for(i=1;i<=Q;i++)
{
a=rd(),l=1,r=s[0]+1;
while(l<r)
{
mid=l+r>>1;
if(s[mid]<=a) l=mid+1;
else r=mid;
}
printf("%d\n",l-1);
}
}
int main()
{
int T=rd();
while(T--)
{
work();
if(T) printf("\n");
}
}

【BZOJ2229】[Zjoi2011]最小割 最小割树的更多相关文章

  1. [bzoj2229][Zjoi2011]最小割_网络流_最小割树

    最小割 bzoj-2229 Zjoi-2011 题目大意:题目链接. 注释:略. 想法: 在这里给出最小割树的定义. 最小割树啊,就是这样一棵树.一个图的最小割树满足这棵树上任意两点之间的最小值就是原 ...

  2. bzoj2229: [Zjoi2011]最小割(分治最小割+最小割树思想)

    2229: [Zjoi2011]最小割 题目:传送门 题解: 一道非常好的题目啊!!! 蒟蒻的想法:暴力枚举点对跑最小割记录...绝对爆炸啊.... 开始怀疑是不是题目骗人...难道根本不用网络流?? ...

  3. scu - 3254 - Rain and Fgj(最小点权割)

    题意:N个点.M条边(2 <= N <= 1000 , 0 <= M <= 10^5),每一个点有个权值W(0 <= W <= 10^5),现要去除一些点(不能去掉 ...

  4. 算法笔记--最大流和最小割 && 最小费用最大流 && 上下界网络流

    最大流: 给定指定的一个有向图,其中有两个特殊的点源S(Sources)和汇T(Sinks),每条边有指定的容量(Capacity),求满足条件的从S到T的最大流(MaxFlow). 最小割: 割是网 ...

  5. 3532: [Sdoi2014]Lis 最小字典序最小割

    3532: [Sdoi2014]Lis Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 865  Solved: 311[Submit][Status] ...

  6. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

  7. POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心)-动态规划做法

    POJ 3659 Cell Phone Network / HUST 1036 Cell Phone Network(最小支配集,树型动态规划,贪心) Description Farmer John ...

  8. 紫书 例题 11-2 UVa 1395(最大边减最小边最小的生成树)

    思路:枚举所有可能的情况. 枚举最小边, 然后不断加边, 直到联通后, 这个时候有一个生成树.这个时候,在目前这个最小边的情况可以不往后枚举了, 可以直接更新答案后break. 因为题目求最大边减最小 ...

  9. BZOJ2229[Zjoi2011]最小割——最小割树

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

随机推荐

  1. HDU 1033 Edge[地图型模拟/给你一串字符串,A代表以此点为参照顺时针90°,V代表逆时针90°]

    Edge Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submis ...

  2. noip2017集训测试赛(三)Problem C: MST

    题面 Description 给定一个n个点m条边的连通图,保证没有自环和重边.对于每条边求出,在其他边权值不变的情况下,它能取的最大权值,使得这条边在连通图的所有最小生成树上.假如最大权值为无限大, ...

  3. shell脚本 linux脚本

    linux:shell 脚本 如果判断当前时间 是不是12点之前 用date命令先取得当前的时间(仅取小时数) : date '+%H'     #按24小时制取hour (00..23) 然后与12 ...

  4. Tmux常用快捷键及命令

    Exported from workflowy! tmux session start/create session- tmux- tmux new-session -s portage listin ...

  5. 基于Bootstrap的页面排版知识

    标题: Bootstrap定义了所有HTML的标题样式,<h1>...<h6>标签或者在标签内加入.h1 class等可以得到一样的效果 效果: 副标题: 标签<smal ...

  6. 2016.7.14 如何在浏览器中查看jsp文件

    参考资料: http://jingyan.baidu.com/article/ed15cb1b10f1241be36981ab.html 1.复制jsp文件地址 2.写在浏览器里 E:/lyh/tas ...

  7. JS门面模式

    门面模式 前言 门面模式的本质是实现一个简单的同一接口来处理对各个子系统接口的处理和调用.和桥接模式不同的是:桥接模式中的各个类是全然独立的,桥接模式仅仅在必要的时候将这些类关联起来. 门面模式则有点 ...

  8. js 小总结

    数组操作 创建数组:var standTerm = new Array("维护","维修"); var arr = new Array(); 数组长度:leng ...

  9. Ubuntu搭建Http服务器

    一句命令: sudo apt-get install apache2 产生的启动和停止文件是:/etc/init.d/apache2 启动:sudo apache2ctl -k start 停止:su ...

  10. json和jsonp以及ajax

    简单的说: JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式. JSON的优点: 1.基于纯文本,跨平台传递极其简单: 2.Javascript原生支持,后 ...