题目描述

学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割。对于带权图来说,将所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而s,t的最小割指的是在关于s,t的割中容量最小的割。
而对冲刺NOI竞赛的选手而言,求带权图中两点的最小割已经不是什么难事了。我们可以把视野放宽,考虑有N个点的无向连通图中所有点对的最小割的容量,共能得到N(N−1)2个数值。
这些数值中互不相同的有多少个呢?这似乎是个有趣的问题。

输入

输入文件第一行包含两个数N,M,表示点数和边数。接下来M行,每行三个数u,v,w,表示点u和点v(从1开始标号)之间有条边权值是w。
1<=N<=850 1<=M<=8500 1<=W<=100000

输出

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

样例输入

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

样例输出

3


题解

分治+最小割,同 bzoj2229 。

最后统计答案时把两点最小割取出来,去个重,求一下个数即可。

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#define N 860
#define M 17010
using namespace std;
queue<int> q;
int n , head[N] , to[M] , val[M] , next[M] , cnt = 1 , s , t , dis[N] , a[N] , tmp[N] , ans[N][N] , v[1000000] , tot;
void add(int x , int y , int z)
{
to[++cnt] = y , val[cnt] = z , next[cnt] = head[x] , head[x] = cnt;
to[++cnt] = x , val[cnt] = z , next[cnt] = head[y] , head[y] = cnt;
}
bool bfs()
{
int x , i;
memset(dis , 0 , sizeof(dis));
while(!q.empty()) q.pop();
dis[s] = 1 , q.push(s);
while(!q.empty())
{
x = q.front() , q.pop();
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && !dis[to[i]])
{
dis[to[i]] = dis[x] + 1;
if(to[i] == t) return 1;
q.push(to[i]);
}
}
}
return 0;
}
int dinic(int x , int low)
{
if(x == t) return low;
int temp = low , i , k;
for(i = head[x] ; i ; i = next[i])
{
if(val[i] && dis[to[i]] == dis[x] + 1)
{
k = dinic(to[i] , min(temp , val[i]));
if(!k) dis[to[i]] = 0;
val[i] -= k , val[i ^ 1] += k;
if(!(temp -= k)) break;
}
}
return low - temp;
}
void solve(int l , int r)
{
if(l >= r) return;
int i , j , sum = 0 , p1 , p2;
for(i = 2 ; i <= cnt ; i += 2) val[i] = val[i ^ 1] = (val[i] + val[i ^ 1]) >> 1;
s = a[l] , t = a[r];
while(bfs()) sum += dinic(s , 1 << 30);
for(i = 1 ; i <= n ; i ++ )
if(dis[i])
for(j = 1 ; j <= n ; j ++ )
if(!dis[j])
ans[i][j] = ans[j][i] = min(ans[i][j] , sum);
for(p1 = i = l , p2 = r ; i <= r ; i ++ )
{
if(dis[a[i]]) tmp[p1 ++ ] = a[i];
else tmp[p2 -- ] = a[i];
}
for(i = l ; i <= r ; i ++ ) a[i] = tmp[i];
solve(l , p2) , solve(p1 , r);
}
int main()
{
int m , i , j , x , y , z , ret = 0;
scanf("%d%d" , &n , &m);
while(m -- ) scanf("%d%d%d" , &x , &y , &z) , add(x , y , z);
for(i = 1 ; i <= n ; i ++ ) a[i] = i;
memset(ans , 0x7f , sizeof(ans)) , solve(1 , n);
for(i = 1 ; i <= n ; i ++ )
for(j = i + 1 ; j <= n ; j ++ )
v[++tot] = ans[i][j];
sort(v + 1 , v + tot + 1);
v[0] = -1 << 30;
for(i = 1 ; i <= tot ; i ++ )
if(v[i] != v[i - 1])
ret ++ ;
printf("%d\n" , ret);
return 0;
}

【bzoj4519】[Cqoi2016]不同的最小割 分治+最小割的更多相关文章

  1. 最小割分治(最小割树):BZOJ2229 && BZOJ4519

    定理:n个点的无向图的最小割最多n-1个. 可能从某种形式上形成了一棵树,不是很清楚. 最小割分治:先任选两个点求一边最小割,然后将两边分别递归,就能找到所有的最小割. 这两个题是一样的,直接搬din ...

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

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

  3. BZOJ 2229 / Luogu P3329 [ZJOI2011]最小割 (分治最小割板题)

    题面 求所有点对的最小割中<=c的数量 分析 分治最小割板题 首先,注意这样一个事实:如果(X,Y)是某个s1-t1最小割,(Z,W)是某个s2-t2最小割,那么X∩Z.X∩W.Y∩Z.Y∩W这 ...

  4. 【BZOJ-4519】不同的最小割 最小割树(分治+最小割)

    4519: [Cqoi2016]不同的最小割 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 393  Solved: 239[Submit][Stat ...

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

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

  6. [bzoj4519][Cqoi2016]不同的最小割_网络流_最小割_最小割树

    不同的最小割 bzoj-4519 Cqoi-2016 题目大意:题目链接. 注释:略. 想法: 我们发现这和最小割那题比较像. 我们依然通过那个题说的办法一样,构建最小割树即可. 接下来就是随便怎么处 ...

  7. BZOJ4519——[cqoi2016]不同的最小割

    0.题意:求两点之间的最小割的不同的总量 1.分析:裸的分治+最小割,也叫最小割树或GH树,最后用set搞一下就好 #include <set> #include <queue> ...

  8. BZOJ4519: [Cqoi2016]不同的最小割

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

  9. ZJOI 最小割 CQOI 不同的最小割 (最小割分治)

    题目1 ZJOI 最小割 题目大意: 求一个无向带权图两点间的最小割,询问小于等于c的点对有多少. 算法讨论: 最小割 分治 代码: #include <cstdlib> #include ...

随机推荐

  1. 最新深度ghost win7系统下载

    深度技术ghost win7系统 64位快速安装版 V2016年2月,深度技术ghost win7 64位快速安装版在不影响大多数软件和硬件运行的前提下,已经尽可能关闭非必要服务,自动安装AMD/In ...

  2. SQLite - WHERE子句

    SQLite - WHERE子句 SQLite WHERE子句用于指定一个条件同时抓取数据从一个表或多个表. 如果给定的条件满意,意味着true,然后从表中返回特定值.你会使用WHERE子句来筛选记录 ...

  3. SQL——SQL语言全部关键字详解

    http://blog.csdn.net/quinnnorris/article/details/71056445 数据库中我们做常用的就是SQL基本查询语言,甚至有些人认为数据库就是SQL,SQL就 ...

  4. 【Linux】Ubuntu18.04镜像下载,新功能介绍

    一.Ubuntu18.04镜像下载 官方下载地址:http://releases.ubuntu.com/18.04/ 官方64位iso下载地址:http://releases.ubuntu.com/1 ...

  5. AC自动机讲解+[HDU2222]:Keywords Search(AC自动机)

    首先,有这样一道题: 给你一个单词W和一个文章T,问W在T中出现了几次(原题见POJ3461). OK,so easy~ HASH or KMP 轻松解决. 那么还有一道例题: 给定n个长度不超过50 ...

  6. sscanf函数详解

    #if 0 ,sscanf():从一个字符串中读进与指定格式相符的数据. ,sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源. ,关于正则表 ...

  7. 原 荐 使用Spring Boot Actuator、Jolokia和Grafana实现准实时监控

    原 荐 使用Spring Boot Actuator.Jolokia和[可视化]Grafana实现准实时监控.   监控系统:          日志- 基础处理 - 表格 - 可视化一体化解决方案. ...

  8. c# DateTime常用用法

    参考:http://sqlyuju.com/c-datetime-hh-hh-qubie.html https://www.cnblogs.com/xiongxiaobai/p/5282827.htm ...

  9. Mac屏幕亮度保存

    关于保存屏幕亮度的方法,论坛上已有几种,搜索 NVRAM 会出来很多教程,在此不再详述,可以参考帖子http://www.idelta.info/archives/nvram_on_hackintos ...

  10. Vue开发微信公众号默认背景为灰色

    最近公司有一个项目,使用Vue开发微信公众号,开发过程遇到一个问题,即设计图的整体背景是白色的,但是公众号里默认的背景是浅灰色,如果某个页面高度没能占满一屏,就会露出浅灰色的默认背景,会显得很不协调. ...