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

两个部分,如果结点\(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. CentOS下利用mysqlbinlog恢复MySQL数据库

    如果不小心对数据库进行误操作,而又没有及时备份怎么办?这恐怕是广大的coder经常遇到的一类问题.我今天就因为不小心删除了某个数据库,但最后的备份是1个礼拜前的,唯一能解决的办法就是通过mysqlbi ...

  2. android开发笔记(2)

    我之前完成了SDK的安装,这次需要在eclipse中导入相关的控件. 一.下载ADT 在之前下载的网站上下载相关的ADT的压缩包. 二.在eclipse中进行导入 在eclipse中的Help-> ...

  3. shell for if

    #!/bin/bash ..} do ];then j="${i}" else j="${i}" fi echo $j >> venn.log ec ...

  4. 2018.11.05 bzoj2143: 飞飞侠(最短路)

    传送门 最短路好题. 考虑对每个二维坐标建立一个高度属性. 这样每次如果在点(i,j,0)(i,j,0)(i,j,0)只能选择花费bi,jb_{i,j}bi,j​跳向(i,j,ai,j)(i,j,a_ ...

  5. PHP函数gmstrftime()将秒数转换成天时分秒

    http://yangjunwei.com/a/930.html PHP函数gmstrftime()将秒数转换成天时分秒   一个应用场景需要用到倒计时的时分秒,比如新浪微博授权有效期剩余: 7天16 ...

  6. idea中Eclipse Code Formatter插件设置和使用,以及注释模板的修改

    在settings里面找到plugins这个选项,搜索Eclipse Code Formatter,点击安装,重启idea即可进行配置: 首先,先安装Eclipse Code Formatter插件: ...

  7. js 上传文件夹

    最近公司做工程项目,实现文件夹上传. 网上找了一天,发现网上很多代码都存在相似问题,最后终于找到了一个符合要求的项目. 工程如下: 这里对项目的文件传输功能做出分析,怎么实现文件夹上传的,如何进行文件 ...

  8. 01-Javascript简介

    Web前端有三层: HTML:从语义的角度,描述页面结构 CSS:从审美的角度,描述样式(美化页面) JavaScript:从交互的角度,描述行为(提升用户体验) JavaScript的组成 Java ...

  9. python advanced programming (Ⅲ)

    IO编程 IO在计算机中指Input/Output.由于程序和运行时数据是在内存中驻留,由CPU来执行,涉及到数据交换的地方,通常是磁盘.网络等,就需要IO接口. IO编程中,Stream(流)是一个 ...

  10. html5打开摄像头并用canvas模拟拍照 - 转

    <video id="video" width="640" height="480" autoplay></video&g ...