Portal

Description

给出一个给出一个\(n(n\leq850)\)个点\(m(m\leq8500)\)条边的无向图。定义\(cut(s,t)\)等于\(s,t\)的最小割的容量,求在所有\(cut(s,t)\)中不同的值有多少个。

Solution

有一个我也想不好为什么的性质:若\(s,t\)的最小割将原图划分成\(S,T\)两个集合,那么\(\forall u\in S,v\in T\),有\(cut(u,v)=cut(s,t)\)。那么我们可以用分治来做。

对于一个点集\(V\),随便选择两个不同的点\(s,t\)并求出最小割和集合\(S,T\)。接下来只要分别考虑\(S\)内部的最小割和\(T\)内部的最小割即可。

我们可以用一个数组\(seq\)上的一个区间\([L,R]\)来代表集合。每次求出\(S,T\)后将\(seq[L..R]\)按\(S\)在前\(T\)在后的顺序重排,这样\(S\)和\(T\)也可以用序列上的区间表示了。

Code

//「CQOI2016」不同的最小割
#include <bits/stdc++.h>
using namespace std;
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
const int N=1e3;
const int INF=0x3F3F3F3F;
int n,m;
int edCnt,h[N];
struct edge{int v,c,nxt;} ed[20*N];
int s,t;
void edAdd(int u,int v,int c)
{
edCnt++; ed[edCnt].v=v,ed[edCnt].c=c,ed[edCnt].nxt=h[u],h[u]=edCnt;
edCnt++; ed[edCnt].v=u,ed[edCnt].c=c,ed[edCnt].nxt=h[v],h[v]=edCnt;
}
int dpt[N]; int op,cl,Q[N];
bool bfs()
{
memset(dpt,0,sizeof dpt);
op=cl=0; dpt[s]=1,Q[++cl]=s;
while(op<cl)
{
int u=Q[++op]; if(u==t) break;
for(int i=h[u];i;i=ed[i].nxt)
{
int v=ed[i].v;
if(!dpt[v]&&ed[i].c) dpt[v]=dpt[u]+1,Q[++cl]=v;
}
}
return dpt[t];
}
int fill(int u,int in)
{
if(u==t||in==0) return in;
int out=0;
for(int i=h[u];i;i=ed[i].nxt)
{
int v=ed[i].v,c=ed[i].c;
if(!c||dpt[v]!=dpt[u]+1) continue;
int fl=fill(v,min(in-out,c));
if(fl==0) dpt[v]=0;
else ed[i].c-=fl,ed[i^1].c+=fl,out+=fl;
if(in==out) break;
}
return out;
}
int Dinic()
{
for(int i=2;i<=edCnt;i+=2) ed[i].c=ed[i^1].c=(ed[i].c+ed[i^1].c)>>1;
int r=0;
while(bfs()) r+=fill(s,INF);
return r;
}
int cnt,seq[N],tmp[N];
int ansCnt,ans[N];
void solve(int L,int R)
{
if(L==R) return;
s=seq[L+R>>1],t=seq[R]; ans[++ansCnt]=Dinic();
int op=L-1,cl=R+1;
for(int i=L;i<=R;i++) tmp[dpt[seq[i]]?++op:--cl]=seq[i];
for(int i=L;i<=R;i++) seq[i]=tmp[i];
solve(L,op),solve(cl,R);
}
int main()
{
n=read(),m=read();
edCnt=1;
for(int i=1;i<=m;i++)
{
int u=read(),v=read(),w=read();
edAdd(u,v,w);
}
for(int i=1;i<=n;i++) seq[i]=i;
solve(1,n);
sort(ans+1,ans+ansCnt+1);
printf("%d\n",unique(ans+1,ans+ansCnt+1)-ans-1);
return 0;
}

LibreOJ2042 - 「CQOI2016」不同的最小割的更多相关文章

  1. LoibreOJ 2042. 「CQOI2016」不同的最小割 最小割树 Gomory-Hu tree

    2042. 「CQOI2016」不同的最小割 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  2. 「CQOI2016」不同的最小割

    「CQOI2016」不同的最小割 传送门 建出最小割树,把每一个点对的最小割抠出来 \(\text{unique}\) 一下就好了. 参考代码: #include <algorithm> ...

  3. loj2042 「CQOI2016」不同的最小割

    分治+最小割 看到题解的第一句话是这个就秒懂了,然后乱七八糟的错误.越界.RE-- #include <algorithm> #include <iostream> #incl ...

  4. 「BZOJ2127」happiness(最小割)

    题目描述 高一一班的座位表是个n*m的矩阵,经过一个学期的相处,每个同学和前后左右相邻的同学互相成为了好朋友.这学期要分文理科了,每个同学对于选择文科与理科有着自己的喜悦值,而一对好朋友如果能同时选文 ...

  5. Codechef RIN 「Codechef14DEC」Course Selection 最小割离散变量模型

    问题描述 提供中文版本好评,一直以为 Rin 是题目名字... pdf submit 题解 参考了 东营市胜利第一中学姜志豪 的<网络流的一些建模方法>(2016年信息学奥林匹克中国国家队 ...

  6. BZOJ2007/LG2046 「NOI2010」海拔 平面图最小割转对偶图最短路

    问题描述 BZOJ2007 LG2046 题解 发现左上角海拔为 \(0\) ,右上角海拔为 \(1\) . 上坡要付出代价,下坡没有收益,所以有坡度的路越少越好. 所以海拔为 \(1\) 的点,和海 ...

  7. LOJ_6045_「雅礼集训 2017 Day8」价 _最小割

    LOJ_6045_「雅礼集训 2017 Day8」价 _最小割 描述: 有$n$种减肥药,$n$种药材,每种减肥药有一些对应的药材和一个收益. 假设选择吃下$K$种减肥药,那么需要这$K$种减肥药包含 ...

  8. loj #2044. 「CQOI2016」手机号码

    #2044. 「CQOI2016」手机号码 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 ...

  9. LibreOJ2044 - 「CQOI2016」手机号码

    Portal Description 给出两个十一位数\(L,R\),求\([L,R]\)内所有满足以下两个条件的数的个数. 出现至少\(3\)个相邻的相同数字: 不能同时出现\(4\)和\(8\). ...

随机推荐

  1. C10 C语言数据结构

    目录 枚举 结构体 共用体 枚举 enum enum枚举是 C 语言中的一种基本数据类型,它可以让数据更简洁,更易读. 枚举语法定义格式为: enum 枚举名 {枚举元素1,枚举元素2,……}; 枚举 ...

  2. 获取kafka的lag, offset, logsize的shell和python脚本

    python脚本 #!/usr/bin/env python import os import re import sys group_id=sys.argv[1] pn=sys.argv[2] ka ...

  3. 剑指offer题目分类

    1. 链表 1. 从尾到头打印链表 2. 链表中倒数第k个结点 3. 反转链表 4. 合并两个排序的链表 5. 复杂链表的复制 6. 复杂链表的复制 7. 两个链表的第一个公共结点 8. 链表中环的入 ...

  4. java基础—基础语法2

    一.语句

  5. DateTime与long互转

    DateTime转long: public static long GetDateLong(object time) { DateTime epoc = TimeZone.CurrentTimeZon ...

  6. 使用Electron开发PC客户端

    最近公司要求开发一个PC客户端,要求不能使用.NET开发(为了不让用户安装.net framework),所以就选择了Electron(随口听别人说了一句,之前从来没有接触过).目前项目要完毕了,所以 ...

  7. 【模拟】HHHOJ#251. 「NOIP模拟赛 伍」高精度

    积累模拟经验 题目描述 维护一个二进制数,支持如下操作 "+" 该数加 11 "-" 该数减 11 "*" 该数乘 22 "\&q ...

  8. PHP redis使用命令

    很有用;以下是redis官方提供的命令使用技巧: 下载地址如下: https://github.com/owlient/phpredis(支持redis 2.0.4) Redis::__constru ...

  9. 图解Disruptor框架(二):核心概念

    图解Disruptor框架(二):核心概念 概述 上一个章节简单的介绍了了下Disruptor,这节就是要好好的理清楚Disruptor中的核心的概念.并且会给出个HelloWorld的小例子. 在正 ...

  10. Python 简单购物程序

    # Author:Eric Zhao# -*- coding:utf-8 -*-'''需求:启动程序后,让用户输入工资,然后打印商品列表允许用户根据商品编号购买商品用户选择商品后,检测余额是否够,够就 ...