4519: [Cqoi2016]不同的最小割

Time Limit: 20 Sec  Memory Limit: 512 MB
Submit:
393  Solved: 239
[Submit][Status][Discuss]

Description

学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成
两个部分,如果结点s,t不在同一个部分中,则称这个划分是关于s,t的割。对于带权图来说,将
所有顶点处在不同部分的边的权值相加所得到的值定义为这个割的容量,而s,t的最小割指的是在
关于s,t的割中容量最小的割。
而对冲刺NOI竞赛的选手而言,求带权图中两点的最小割已经不是什么难事了。我们可以把
视野放宽,考虑有N个点的无向连通图中所有点对的最小割的容量,共能得到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

HINT

Source

Solution

跟上一题的做法很像,分治最小割

记录答案即可,最后排序看看有多少不同的即可.....

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
#define maxn 1000
#define maxm 100010
int n,m,q,t,ans[maxn],tot,id[maxn],tmp[maxn];
struct Edgenode{int next,to,cap;}edge[maxm];
int head[maxn],cnt=;
void add(int u,int v,int w)
{cnt++; edge[cnt].to=v; edge[cnt].next=head[u]; head[u]=cnt; edge[cnt].cap=w;}
void insert(int u,int v,int w) {add(u,v,w); add(v,u,w);}
int dis[maxn],que[maxn<<],cur[maxn],S,T;
bool bfs()
{
memset(dis,-,sizeof(dis));
que[]=S; dis[S]=; int he=,ta=;
while (he<ta)
{
int now=que[he++];
for (int i=head[now]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==-)
dis[edge[i].to]=dis[now]+,que[ta++]=edge[i].to;
}
return dis[T]!=-;
}
int dfs(int loc,int low)
{
if (loc==T) return low;
int w,used=;
for (int i=cur[loc]; i; i=edge[i].next)
if (edge[i].cap && dis[edge[i].to]==dis[loc]+)
{
w=dfs(edge[i].to,min(low-used,edge[i].cap));
edge[i].cap-=w; edge[i^].cap+=w;
used+=w; if (edge[i].cap) cur[loc]=i;
if (used==low) return low;
}
if (!used) dis[loc]=-;
return used;
}
#define inf 0x7fffffff
int dinic()
{
int tmp=;
while (bfs())
{
for (int i=; i<=n; i++) cur[i]=head[i];
tmp+=dfs(S,inf);
}
return tmp;
}
void init()
{
cnt=;
memset(ans,,sizeof(ans));
memset(head,,sizeof(head));
}
bool visit[maxn];
void DFS(int x)
{
visit[x]=;
for (int i=head[x]; i; i=edge[i].next)
if (edge[i].cap && !visit[edge[i].to])
DFS(edge[i].to);
}
void work(int L,int R)
{
if (L==R) return;
for (int i=; i<=cnt; i+=)
edge[i].cap=edge[i^].cap=(edge[i].cap+edge[i^].cap)>>;
S=id[L],T=id[R];
int maxflow=dinic();
memset(visit,,sizeof(visit)); DFS(S);
ans[++tot]=maxflow;
int l=L,r=R;
for (int i=L; i<=R; i++)
if (visit[id[i]])
tmp[l++]=id[i];
else tmp[r--]=id[i];
for (int i=L; i<=R; i++) id[i]=tmp[i];
work(L,l-); work(r+,R);
}
int main()
{
init();
n=read(),m=read();
for (int i=; i<=n; i++) id[i]=i;
for (int u,v,w,i=; i<=m; i++)
u=read(),v=read(),w=read(),insert(u,v,w);
work(,n);
sort(ans+,ans+tot+);
int an=;
for (int i=; i<=tot; i++) if (ans[i]!=ans[i-]) an++;
printf("%d\n",an);
return ;
}

滚回来学校期中考试,考前就是不复习的刷水题1A的乐趣.....

【BZOJ-4519】不同的最小割 最小割树(分治+最小割)的更多相关文章

  1. BZOJ 3218 UOJ #77 A+B Problem (主席树、最小割)

    大名鼎鼎的A+B Problem, 主席树优化最小割-- 调题死活调不对,一怒之下改了一种写法交上去A了,但是改写法之后第4,5个点常数变大很多,于是喜提UOJ全站倒数第三 目前还不知道原来的写法为什 ...

  2. BZOJ 4367 [IOI2014]holiday (决策单调DP+主席树+分治)

    题目大意:略 题目传送门 神题,不写长题解简直是浪费了这道题 贪心 考虑从0节点出发的情况,显然一直往前走不回头才是最优策略 如果起点是在中间某个节点$s$,容易想到,如果既要游览$s$左边的某些景点 ...

  3. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)

    传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...

  4. bzoj 4519: [Cqoi2016]不同的最小割 最小割树

    怎么求一张无向图中任意两点之间的最小割? http://fanhq666.blog.163.com/blog/static/8194342620113495335724/ 一张无向图不同的最小割最多有 ...

  5. BZOJ 4519 [CQOI2016]不同的最小割

    这道题目很奇怪. 为什么奇怪?因为这道题用了一种叫分治最小割/最小割树的玩意. 以前从来没有见过这东西. 推荐一个讲这玩意的博客 写起来还是很顺手的. #include<iostream> ...

  6. BZOJ 4435 [Cerc2015]Juice Junctions 分治最小割+hash

    分治最小割的题目,要求n2. 之前用的n3的方法自然不能用了. 于是用hash,设hash[i][j]表示在最小割为i的时候,j是否与S联通. 看懂这个需要理解一下最小割树的构造. 这种题建议用EK写 ...

  7. BZOJ 2039:[2009国家集训队]employ人员雇佣(最小割)

    http://www.lydsy.com/JudgeOnline/problem.php?id=2039 题意:中文题意. 思路:一开始想着和之前做的最大权闭合图有点像,但是如果把边全部当成点的话,那 ...

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

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

  9. 【BZOJ-4435】Juice Junctions 最小割树(分治+最小割)+Hash

    4435: [Cerc2015]Juice Junctions Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 20  Solved: 11[Submi ...

随机推荐

  1. Centos6 修改max user processes limits

    ulimit:显示(或设置)用户可以使用的资源的限制(limit),这限制分为软限制(当前限制)和硬限制(上限),其中硬限制是软限制的上限值,应用程序在运行过程中使用的系统资源不超过相应的软限制,任何 ...

  2. Linux shell的输入输出

    echo --echo命令可以显示文本行或变量,或者把字符串输入到文件 --echo [option] string -e 解析转义字符 例如:echo -e "nimenhao\nasfd ...

  3. 东大OJ-Prim算法

    1222: Sweep the snow 时间限制: 1 Sec  内存限制: 128 MB 提交: 28  解决: 18 [提交][状态][讨论版] 题目描述 After the big big s ...

  4. Oracle sql develpoer

    Oracle SQL Developer是针对Oracle数据库的交互式开发环境(IDE)     Oracle SQL Developer简化了Oracle数据库的开发和管理. SQL Develo ...

  5. 34-nl 简明笔记

    为文本文件添加行号 nl [options] files 参数 files是nl需要为其添加行号的文本文件路径名,如果有多个文件,则nl会把多个文件合在一起编号,并输出到标准输出上 选项 -b     ...

  6. Maven的set.xml标签详解

    文件存放位置 全局配置: ${M2_HOME}/conf/settings.xml 用户配置: ${user.home}/.m2/settings.xml note:用户配置优先于全局配置.${use ...

  7. json注意:

    import json #dct="{'1':111}"#json 不认单引号 #dct=str({"1":111})#报错,因为生成的数据还是单引号:{'on ...

  8. Oracle之物化视图

    来源于:http://www.cnblogs.com/Ronger/archive/2012/03/28/2420962.html 近期根据项目业务需要对oracle的物化视图有所接触,在网上搜寻关于 ...

  9. Web Api单元测试写法

    例如我们在Web Api项目中有个Controller public class SomeController : ApiController { public HttpResponseMessage ...

  10. Swift开发小技巧--TabBar中间按钮的添加方案

    TabBar中间按钮的添加方案 之前做百思项目的时候,也有一个中间按钮,当时是重写的TabBar,这里介绍一个新的方法 给TabbarVC多添加添加一个控制器,这个控制器的作用仅仅是用来占位的,多了这 ...