HDU 6214【最少的最小割边数】

题目大意如题。

这道题想了很久也没明白题解的做法:

建边的时候每条边权 w = w * (E + 1) + 1;
这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1)

总之先把它当成黑科技背着吧

#include<stdio.h>
#include<string.h>
#include<queue>
using namespace std;
struct node {
    int from;
    int to;
    int w;
    int next;
}e[160000];
int cur[1500];
int head[1500];
int divv[1500];
int cont, ss, tt;
void add(int from, int to, int w) {
    e[cont].from = from;
    e[cont].w = w;
    e[cont].to = to;
    e[cont].next = head[from];
    head[from] = cont++;
}
int n, m; int makedivv() {
    memset(divv, 0, sizeof(divv));
    divv[ss] = 1;
    queue<int >s;
    s.push(ss);
    while (!s.empty()) {
        int u = s.front();
        if (u == tt)return 1;
        s.pop();
        for (int i = head[u]; i != -1; i = e[i].next) {
            int w = e[i].w;
            int v = e[i].to;
            if (divv[v] == 0 && w) {
                divv[v] = divv[u] + 1;
                s.push(v);
            }
        }
    }
    return 0;
}
int Dfs(int u, int maxflow, int tt) {
    if (u == tt)return maxflow;
    int ret = 0;
    for (int &i = cur[u]; i != -1; i = e[i].next) {
        int v = e[i].to;
        int w = e[i].w;
        if (divv[v] == divv[u] + 1 && w) {
            int f = Dfs(v, min(maxflow - ret, w), tt);
            e[i].w -= f;
            e[i ^ 1].w += f;
            ret += f;
            if (ret == maxflow)return ret;
        }
    }
    return ret;

}
void Dinic() {
    long long int ans = 0;
    while (makedivv() == 1) {
        memcpy(cur, head, sizeof(head));
        ans += Dfs(ss, 0x3f3f3f3f, tt);
    }
    printf("%lld\n", ans % 100000);
}

int main() {
    int t;
    scanf("%d", &t);
    while (t--) {
        scanf("%d%d", &n, &m);
        scanf("%d%d", &ss, &tt);
        cont = 0;
        memset(head, -1, sizeof(head));
        for (int i = 0; i < m; i++) {
            int x, y, z;
            scanf("%d%d%d", &x, &y, &z);
            z = z * 100000 + 1;
            add(x, y, z); add(y, x, 0);
        }
        Dinic();
    }
}

原文地址:https://www.cnblogs.com/tennant/p/8970825.html

时间: 2024-10-10 04:26:05

HDU 6214【最少的最小割边数】的相关文章

HDU 6214 最小割边

双倍经验题:HDU 6214,3987 求最小割的最小边. 方案一: 首先跑最大流,这个时候割上都满载了,于是将满载的边 cap = 1,其他 inf ,再跑最大流,这个时候限定这个网络的关键边就是那个最少边的那个割. 方案二: 奇技淫巧,将每条边 cap* A + 1,最大流 = flow / A ,最小割边 = fow % A: 原理:每条边容量扩大 到 cap * A + 1,那么最大流也一定扩大到 *A + 1,原图是多解,但是新图, 例如最少边的个是2条边,那么他就扩大到了 *A +

hdu 3987 Harry Potter and the Forbidden Forest 求割边最少的最小割

view code//hdu 3987 #include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; typedef long long ll; const ll INF = 1LL<<59; const ll E = 100001; const int N = 10

HDU 6214 Smallest Minimum Cut 最小割,权值编码

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6214 题意:求边数最小的割. 解法: 建边的时候每条边权 w = w * (E + 1) + 1; 这样得到最大流 maxflow / (E + 1) ,最少割边数 maxflow % (E + 1) 道理很简单,如果原先两类割边都是最小割,那么求出的最大流相等 但边权变换后只有边数小的才是最小割了 乘(E+1)是为了保证边数叠加后依然是余数,不至于影响求最小割的结果 因为假设最小割=k,那么现在新

割边最少的最小割求法两种(仅结论)

我太弱了,所以只贴上结论,省略(不会)证明. 求法一: 1.求出原网络的最大流. 2.把可能的关键割边(即满流的边)容量置为 1,其余边容量置为 0. 3.求出修改后网络的最大流. 此时的最大流即是最小割时最少的割边数. 总共求了 2 次最大流. 更好的求法二: 以下用 E 表示网络流中的边数. 1.建图时,把每条边的边权 w 置为 w * (E + 1) + 1. 2.求出修改后网络的最大流 flow_max. 此时原图的最大流为 flow_max / (E + 1) ,最少的割边数为 flo

hdu 1728 bfs 最小拐弯数

链接:http://acm.hdu.edu.cn/showproblem.php?pid=1728 之前没有做过类似这种要最少拐弯数的题目,一般求最少的用bfs应该比较好..但是之前bfs一般都是用来求最小步数,也就可以标记过走过的点不再走.现在本题要的是最小的拐弯数,所以不能标记走过的点..需要一个数组来记录当前这个点所需要的最小拐弯数,如果此时这个点的拐弯数比之前该点的拐弯数还小或者等于就更新这个值.遍历全图直到找到解为止. 学习:对于bfs找最优解的变形.明白如何更新拐弯数的,保证最小.

hdu 6214 Smallest Minimum Cut[最大流]

hdu 6214 Smallest Minimum Cut[最大流] 题意:求最小割中最少的边数. 题解:对边权乘个比边大点的数比如300,再加1 ,最后,最大流对300取余就是边数啦.. 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #in

HDU 5294--Tricks Device【最小割 &amp;&amp; 最短路处理,新建图】

Tricks Device Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 2208    Accepted Submission(s): 584 Problem Description Innocent Wu follows Dumb Zhang into a ancient tomb. Innocent Wu's at the en

一文讲透Dubbo负载均衡之最小活跃数算法

本文是对于Dubbo负载均衡策略之一的最小活跃数算法的详细分析.文中所示源码,没有特别标注的地方均为2.6.0版本. 为什么没有用截止目前的最新的版本号2.7.4.1呢?因为2.6.0这个版本里面有两个bug.从bug讲起来,印象更加深刻. 最后会对2.6.0/2.6.5/2.7.4.1版本进行对比,通过对比学习,加深印象. 本文目录 第一节:Demo准备. 本小节主要是为了演示方便,搭建了一个Demo服务.Demo中启动三个服务端,负载均衡策略均是最小活跃数,权重各不相同. 第二节:断点打在哪

hdu 5177 (1e18范围的卡特兰数)

hdu 5177 (1e18范围的卡特兰数) 题意: 求第n个卡特兰数,模3814697265625 (5^18) 限制: 有20组数据,1 <= n <= 1e18 思路: 1. 卡特兰数的表达式: ans = 1/(n+1) * C(2*n,n) -> ans = 1/(n+1) * (2n)! / n! / n!    ---1式 2. 因为要模5^18,求逆元要求互质,所以先把"1式"中的因子5全部去掉 3. 然后看不含因子5的阶乘,f(n!) 4. 设g(x