【网络流24题】 P2774 方格取数问题 最小割

利用网络流求解P2774方格取数问题,将方格图构建成二分图,通过最小割方法找到最大和,确保相邻方格互斥,最终达到损失最小的最大取数和。

有一个 mm 行 nn 列的方格图,每个方格中都有一个正整数。现要从方格中取数,使任意两个数所在方格没有公共边,且取出的数的总和最大,请求出最大的和。

思路:任意一个方格都和周围四个互斥,那么就构成了一个二分图,且可以用(i+j)的奇偶性区分两部。
我们想要实现选or不选某个点(在二分图中),来看有没有把它的值加入贡献。考虑网络流,让源点向其中一部连流量为对应值的边,另一部向汇点连流量为对应值的边。二分图内部连流量无限。
建图完后,会发现问题转化成了割掉多少边使得损失最小,这就是一个求最小割的问题了。
关于正确性,由于二分图内部是流量无限的边,那么肯定不会割这条边,只会删源点和汇点所连的边。这样的话,残留图如s->1->2,代表选了结点1没选结点2,3->4->t则代表选了结点4没选结点3。又因为损失最小,所以残留图的权值和就是答案(最大和)。

view code
#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include <queue>
#include<sstream>
#include <stack>
#include <set>
#include <bitset>
#include<vector>
#define FAST ios::sync_with_stdio(false)
#define abs(a) ((a)>=0?(a):-(a))
#define sz(x) ((int)(x).size())
#define all(x) (x).begin(),(x).end()
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)
#define endl '\n'
#define pb push_back
#define mp make_pair
#define ac cout<<ans<<endl
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> PII;
const int maxn = 2e2+200;
const ll inf=0x3f3f3f3f3f3f3f3f;
const double eps = 1e-7;
const double pi=acos(-1.0);
const int mod = 1e9+7;
inline int lowbit(int x){
   
   return x&(-x);}
ll gcd(ll a,ll b){
   
   return b?gcd(b,a%b):a;}
void ex_gcd(ll a,ll b,ll &d,ll &x,ll &y){
   
   if(!b){
   
   d=a,x=1,y=0;}else{
   
   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值