学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成

两个部分,如果结点\(s,t\)不在同一个部分中,则称这个划分是关于\(s,t\)的割。对于带权图来说,将

所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而\(s,t\)的最小割指的是在

关于\(s,t\)的割中容量最小的割。

而对冲刺\(NOI\)竞赛的选手而言,求带权图中两点的最小割已经不是什么难事了。我们可以把

视野放宽,考虑有\(N\)个点的无向连通图中所有点对的最小割的容量,共能得到\(\frac{N(N−1)}{2}\)个数值。

这些数值中互不相同的有多少个呢?这似乎是个有趣的问题。

Input

输入文件第一行包含两个数\(N\),\(M\),表示点数和边数。接下来M行,每行三个数\(u,v,w\),

表示点\(u\)和点\(v\)(从1开始标号)之间有条边权值是\(w\)。\(1<=N<=850,1<=M<=8500,1<=W<=100000\)

Output

输出文件第一行为一个整数,表示个数。

Sample Input

4 4
1 2 3
1 3 6
2 4 5
3 4 4

Sample Output

3

题意:

中文题面,不解释

题解:

最小割树统计出所有最小割,然后计数就行了

#include<bits/stdc++.h>
#define re register
using namespace std;
const int inf=1<<29,N=1010,M=20010;
int n,m,a[N];
int ans[N][N];
int head[N],nxt[M],bian[M],zhi[M],tot;
map<int,int>mp;
void init(){
tot=1;
memset(head,0,sizeof head);
}
void add(int x,int y,int 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,z;
scanf("%d%d%d",&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;
}
int dinic(int b,int e,int x,int flow){
if(x==e)return flow;
int 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 int maxflow(int b,int e){
int 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 int mincut=maxflow(b,e);
mp[mincut]=1;
memset(v,0,sizeof v);
cut(b);
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;
memset(ans,0x3f,sizeof ans);
cin>>n>>m;
init();
build(m);
for(int i=1;i<=n;++i){
a[i]=i;
}
solve(1,n);
map<int,int>::iterator it;
int ans=0;
for(it=mp.begin();it!=mp.end();++it){
ans++;
}
cout<<ans<<endl;
}
?

不同的最小割(cqoi2016,bzoj4519)(最小割树)的更多相关文章

  1. [ZJOI2011]最小割 & [CQOI2016]不同的最小割 分治求最小割

    题面: [ZJOI2011]最小割 [CQOI2016]不同的最小割 题解: 其实这两道是同一道题.... 最小割是用的dinic,不同的最小割是用的isap 其实都是分治求最小割 简单讲讲思路吧 就 ...

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

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

  3. 最小割(zjoi2011,bzoj2229)(最小割树)

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

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

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

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

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

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

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

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

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

  8. 二分图变种之最小路径覆盖、最小点覆盖集【poj3041】【poj2060】

    [pixiv] https://www.pixiv.net/member_illust.php?mode=medium&illust_id=54859604 向大(hei)佬(e)势力学(di ...

  9. EBS oracle 批量导入更新MOQ(最小拆分量、采购提前期、最小订购量、最小包装量)

    EXCEL的列:组织id,供应商编号,供应商地点,料号,最小拆分量.采购提前期.最小订购量.最小包装量 --采购导入更新MOQ四个值,若有为空的那列,会保留原来的值,不会去更新那列的值 PROCEDU ...

随机推荐

  1. kbmMW均衡负载与容灾(3)(转载红鱼儿)

    在kbmMW均衡负载与容灾(1)中,介绍了利用ClientTransport的OnReconnect事件,对联接的应用服务器的地址进行更换,做容灾处理.实际上,作者还给我们提供了另外一种机制,直接在C ...

  2. ps中为什么在图片上面添加不了文字

    我们在使用PS对某些图片进行处理时,往往会添加一些文字:但有时因图片格式问题,导致添加文字是一个小黑点,无法看清,下面就为大家讲解一下具体的处理方法. 工具/原料   Photoshop CS5.图片 ...

  3. 2018.11.04 洛谷P2679 子串(线性dp)

    传送门 为什么前几年的noipnoipnoip总是出这种送分题啊? 这个直接线性dpdpdp不就完了吗? f[i][j][k][0/1]f[i][j][k][0/1]f[i][j][k][0/1]表示 ...

  4. mac os下提高android studio运行速度终极方法

    /Users/hangliao/ 删除(.android  .gradle)两个文件夹 android studio恢复所有设置到初始化状态,这样会删除已创建的模拟器,所以需从创建一下模拟器 mac ...

  5. Le Chapitre IV

    J'avais ainsi appris une seconde chose très importante: C'est que sa planète d'origine était à peine ...

  6. pyinstaller基本操作

    pyinstaller 打包错误http://www.fmwei.com/linux/pyinstaller-lib-error.html 只需要复制python安装目录下的动态库到系统地动态库目录即 ...

  7. C++STL stack

    stack栈 先进后出 stack<int> s ; s.push();//元素入栈 //出栈 while(!s.empty()){ int tmp = s.top(); s.pop(); ...

  8. 研究生flag

    是时候定个计划了,感觉日子一天天水,不加油学点东西,迟早要掉队…… 刷刷算法题库吧,貌似选几个管用的刷刷——https://hihocoder.com/problemset 争取明年三月份的PAT顶级 ...

  9. 怎么让挨着的两input之间没有空隙?

    问题:在写选项卡的时候,用input做点击事件的切换时,两个input之间会有空隙,使用margin/padding为0或者为负数依旧如此  → 解决:我脑慢的最后才想到是空格影响的,呵呵呵.

  10. 强大的DataGrid组件[1]

    说明:DataGrid组件是Silverlight数据组件中最为常用并且是功能最为强大的数据组件.因此,对开发者而言,深入了解其特性是十分有必要的.本文先介绍该组件的基本特性,接着通过几个简单实例来说 ...