0、题意:求两点之间的最小割的不同的总量

1、分析:裸的分治+最小割,也叫最小割树或GH树,最后用set搞一下就好

#include <set>
#include <queue>
#include <ctime>
#include <cstdio>
#include <cstring>
#include <cstring>
#include <algorithm>
using namespace std;
#define LL long long
#define inf 214748364

struct Edge{
    int from, to, cap, flow, next;
};
int head[1010], cur[1010];
Edge G[40010];
int tot;
int d[1010];
bool vis[1010];
int s, t, n, m;
int a[1010];
int b[1010];

inline void init(){
    memset(head, -1, sizeof(head));
    tot = -1;
    return;
}

inline void insert(int from, int to, int cap){
    G[++ tot] = (Edge){from, to, cap, 0, head[from]};
    head[from] = tot;
    G[++ tot] = (Edge){to, from, 0, 0, head[to]};
    head[to] = tot;
    return;
}

inline bool BFS(){
    memset(vis, 0, sizeof(vis));
    queue<int> Q;
    Q.push(s);
    vis[s]=1;
    d[s]=0;
    while(!Q.empty()){
        int x = Q.front(); Q.pop();
        for(int i = head[x]; i != -1; i = G[i].next){
            Edge& e = G[i];
            if(e.cap - e.flow > 0 && !vis[e.to]){
                vis[e.to] = 1;
                d[e.to]=d[x]+1;
                Q.push(e.to);
            }
        }
    }
    return vis[t];
}

inline int dfs(int x, int a){
    if(x == t || a == 0) return a;
    int flow = 0, f;
    for(int& i = cur[x]; i != -1; i = G[i].next){
        Edge& e = G[i];
        if(d[x]+1 == d[e.to] && (f = dfs(e.to, min(e.cap - e.flow, a))) > 0){
            e.flow += f;
            G[i ^ 1].flow -= f;
            flow += f;
            a -= f;
            if(a == 0) break;
        }
    }
    return flow;
}

inline int maxflow(){
    int res = 0;
    while(BFS()){
        for(int i = 1; i <= n; i ++) cur[i] = head[i];
        res += dfs(s, inf);
    }
    return res;
}

inline void DFS(int x){
    vis[x] = 1;
    for(int i = head[x]; i != -1; i = G[i].next) if(!vis[G[i].to] && G[i].cap > G[i].flow){
        DFS(G[i].to);
    }
}

inline void Clear(){
    for(int i = 0; i <= tot; i += 2){
        G[i].flow = G[i ^ 1].flow = (G[i].flow + G[i ^ 1].flow) / 2;
    }
}

set<int> Set;

inline void solve(int l, int r){
    if(l == r) return;
    s = a[l], t = a[r];
    Clear();

    int tw = maxflow();
    Set.insert(tw);
    int L = l, R = r;
    for(int i = l; i <= r; i ++){
        if(vis[a[i]]) b[L ++] = a[i];
        else b[R --] = a[i];
    }
    for(int i = l; i <= r; i ++) a[i] = b[i];
    solve(l, L - 1); solve(L, r);
}

int main(){
    scanf("%d%d", &n, &m);
    init();
    for(int i = 1; i <= m; i ++){
        int u, v, w;
        scanf("%d%d%d", &u, &v, &w);
        insert(u, v, w); insert(v, u, w);
    }
    for(int i = 1; i <= n; i ++) a[i] = i;
    solve(1, n);
    printf("%d\n", Set.size());
    return 0;
}

BZOJ4519——[cqoi2016]不同的最小割的更多相关文章

  1. bzoj千题计划140:bzoj4519: [Cqoi2016]不同的最小割

    http://www.lydsy.com/JudgeOnline/problem.php?id=4519 最小割树 #include<queue> #include<cstdio&g ...

  2. bzoj4519: [Cqoi2016]不同的最小割(分治最小割)

    4519: [Cqoi2016]不同的最小割 题目:传送门 题解: 同BZOJ 2229 基本一样的题目啊,就最后用set记录一下就ok 代码: #include<cstdio> #inc ...

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

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

  4. BZOJ4519 CQOI2016不同的最小割(最小割+分治)

    最小割树:新建一个图,包含原图的所有点,初始没有边.任取两点跑最小割,给两点连上权值为最小割的边,之后对于两个割集分别做同样的操作.最后会形成一棵树,树上两点间路径的最小值即为两点最小割.证明一点都不 ...

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

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

  6. BZOJ4519[Cqoi2016]不同的最小割——最小割树+map

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

  7. bzoj4519: [Cqoi2016]不同的最小割(最小割树)

    传送门 好神仙……最小割树是个什么东西…… 其实我觉得干脆直接$O(n^2)$跑几个dinic算了…… 来说一下这个叫最小割树的神奇东西 我们先建一个$n$个点,没有边的无向图 在原图中任选两点$s, ...

  8. 【BZOJ4519】[Cqoi2016]不同的最小割 最小割树

    [BZOJ4519][Cqoi2016]不同的最小割 Description 学过图论的同学都知道最小割的概念:对于一个图,某个对图中结点的划分将图中所有结点分成两个部分,如果结点s,t不在同一个部分 ...

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

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

随机推荐

  1. gettextize与glib-gettextize的使用

    gettextize在各种场合都可以使用,用于支持多语言开发 glib-gettextize运行后,会修改po/Makefile.in.in文件,导致后续都必须运行glib-gettextize ge ...

  2. 在C#中使用官方驱动操作MongoDB

    MongoDB的官方驱动下载地址:https://github.com/mongodb/mongo-csharp-driver/releases 目前最新的版本是2.10,支持.NET 4.5以上.由 ...

  3. aircrack-ng test

    Aircrack-ng工具包有很多工具,我用到的工具主要有以下几个: airmon-ng 处理网卡工作模式 airodump-ng 抓包 aircrack-ng 破解 aireplay-ng 发包,干 ...

  4. c#根据公式进行自动计算 四个5加减乘除=4

        想不出来就采用枚举法吧,代码写起来还是很简单的,当然代码写的不怎么样,也不考虑设计效率等等问题了,理论上这种类型的都可以这么拼出来,比较初级的做法,但轻松解决问题.注意Calculate(st ...

  5. 表单提交set集合问题

    提交时使用数组接收,遍历将数组添加到set集合 用户表user 字段id,name,set<xk> xks=new HashSet<xk>(); 选课表xk 字段id,name ...

  6. LVS工作总结之原理篇–DR模式

    原文地址: http://www.chenqing.org/2012/11/%E3%80%90lvs%E3%80%91lvs%E5%B7%A5%E4%BD%9C%E6%80%BB%E7%BB%93%E ...

  7. Aspect Oriented Programming using Interceptors within Castle Windsor and ABP Framework AOP

    http://www.codeproject.com/Articles/1080517/Aspect-Oriented-Programming-using-Interceptors-wit Downl ...

  8. Java基础笔记 – Annotation注解的介绍和使用 自定义注解

    Java基础笔记 – Annotation注解的介绍和使用 自定义注解 本文由arthinking发表于5年前 | Java基础 | 评论数 7 |  被围观 25,969 views+ 1.Anno ...

  9. 把字符转换为 HTML 实体

    把字符转换为HTML实体:htmlentities() 把HTML实体转换回字符:html_entity_decode() 把预定义的字符 "<" (小于)和 "& ...

  10. 解决redhat的未注册问题

    昨天安装第五步的时候:开始是没有网,,,居然ping不通  网  ,服务器也ping不通,,,,,可能和我前几天删除了网络适配器有关,,把linux桥接对应的适配器给删了,,, 解决办法是打开虚拟网络 ...