Nubulsa Expo. 全局最小割

本文介绍了一个基于C++实现的最小割算法,通过不断合并顶点来寻找网络中最小的割集,适用于解决最大流问题中的最小割求解。文章提供了完整的代码示例,并解释了如何初始化图以及添加边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


#include <bits/stdc++.h>
//点标从0-n-1, 开始时先init 复杂度n^3
//对于边(u,v,flow):
//g[u][v]+=flow;
//g[v][u]+=flow;
typedef long long ll;
const int N = 305;
const ll inf = 1e18;
ll g[N][N], w[N];
int a[N], v[N], na[N];
void add_edge(int u , int v , int flow){
    g[u][v] += flow ;
    g[v][u] += flow ;
}
ll mincut(int n) {
	int i, j, pv, zj;
	ll best = inf;
	for(i = 0; i < n; i ++) v[i] = i;

	while(n > 1) {
		for(a[v[0]] = 1, i = 1; i < n; i ++) {
			a[v[i]] = 0;
			na[i-1] = i;
			w[i] = g[v[0]][v[i]];
		}
		for(pv = v[0], i = 1; i < n; i ++) {
			for(zj = -1, j = 1; j < n; j ++)
				if(!a[v[j]] && (zj < 0 || w[j] > w[zj])) zj = j;

			a[v[zj]] = 1;
			if(i == n-1) {
				if(best > w[zj]) best = w[zj];
				for(i = 0; i < n; i ++) {
					g[v[i]][pv] = g[pv][v[i]] += g[v[zj]][v[i]];
				}
				v[zj] = v[--n];
				break;
			}
			pv = v[zj];
			for(j = 1; j < n; j ++) if(!a[v[j]])
				w[j] += g[v[zj]][v[j]];
		}
	}
	return best;
}
void init(int n){
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n; j ++)
            g[i][j] = g[j][i] = 0;
}

int main()
{
    int n , m , st ;
    while( ~ scanf("%d %d %d" , & n , & m , & st ))
    {
        if(!n && !n && !st) break ;
        init(n) ;
        int a , b , c;
        for(int i = 0 ; i < m ; i ++ ){
            scanf("%d %d %d" , &a , &b , &c) ;
            add_edge(a - 1 , b - 1 , c) ;
        }
        printf("%lld\n" , mincut(n)) ;
    }
    return 0 ;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值