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. CSS3-box-flex弹性盒布局

    <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8" ...

  2. BZOJ3160: 万径人踪灭

    设a[i]=bool(s[i]=='a'),b[i]=bool(s[i]=='b'),考虑a和a.b和b的卷积,由于卷积是对称的,就可以统计出不连续回文子串个数了.可能说得比较简略.再用manache ...

  3. css中 Span 元素的 width 属性无效果原因及多种解决方案

    先运行下程序看下: <span style='width:300px;'>123</span> 输出:123 可以看到 span会自动根据包含的内容来变化宽度 这是因为:对于内 ...

  4. docker mysql

    创建mysql docker容器 github上有一个专门的docker-libary项目,里面有各种各样常用的docker镜像,可以做为学习的示例,今天研究下其中mysql镜像的用法,国内镜像dao ...

  5. orancle的安装和配置

    1.安装 Oracle 版本:Oracle Database 10g Release 2 (10.2.0.1) 下载地址: http://www.oracle.com/technology/softw ...

  6. CentOS只允许部分IP登陆ssh |ssh 允许指定IP

    在/etc/hosts.allow输入   (其中192.168.10.88是你要允许登陆ssh的ip,或者是一个网段192.168.10.0/24)   sshd:192.168.10.88:all ...

  7. 自然语言13_Stop words with NLTK

    https://www.pythonprogramming.net/stop-words-nltk-tutorial/?completed=/tokenizing-words-sentences-nl ...

  8. c++编译错误提示及解决

    IntelliSense: #error 指令: Please use the /MD switch for _AFXDLL builds 修改设置:工程(Project)-> 属性(Prope ...

  9. Java字符串方法

    1.字符串和字符数组的转换 .toCharArray() String str1 = "hello"; // //System.out.println(str1); char c[ ...

  10. JavaScript排序算法——快速排序

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...