【题解】P4003 无限之环

前言
我嘞个费用流啊,我勒个建模好题啊

题意

link

在这里插入图片描述

简述:
在一个 n × m n\times m n×m 的网格图内有一些水管,问能否拼成不漏水的形状。

题解

分析

看到方格图,按照套路,考虑对原图进行黑白染色。

然后看看这个图有什么用,考虑将源点连向所有黑点,所有白点连向汇点,然后直接跑最小费用最大流,如果 2 × 2\times 2× 最大流量 = = =接口数,那么解即为最小费用,否则无解。

因为每一个白点接口和每一个黑点接口匹配上,就可以产生 1 1 1 点贡献,所以总贡献因为接口总数的一半,否则就有接口匹配不上,就漏水了。

怎么建图呢?考虑拆点,将每一个点拆成上,下,左,右,中五个点,中点连向源点或汇点,其余四个点和异种颜色的这四类点匹配。

重中之重来了——怎么旋转。

以黑点为例(白点的边要反过来)

先考虑最简单的: 000 1 ( 2 ) 0001_{(2)} 0001(2)

如图:

考虑连一条红边,流量为 1 1 1,费用为 0 0 0,这是这个水管的基本数据。

那旋转呢?

考虑连蓝边,流量为 1 1 1,费用 > 0 >0 >0

如图:

蓝边第一个数为流量,第二个数为费用,这样我们就可以模拟旋转操作了。只需要计算出相应的费用即可。

再深入一点,我们用红边限制流量,用蓝边模拟旋转。

接下来是 T 型,如图:

这个各位读者可以思考一下为什么是连 3 3 3 条边,且费用为什么为那些数,最好模拟一下。

然后是 L 型,如图:

剩下的都差不多,不画了。

Code

参考的核心代码:

#include<bits/stdc++.h>
#define int long long
#define IOS ios::sync_with_stdio(false),cin.tie(NULL),cout.tie(NULL)
#define cou(i) cout<<fixed<<setprecision(i)
using namespace std;
const int N=2e3+1,M=2e6+1,inf=1e9;
int n,m,k,s,t,o,ans,mi_c,idx=1,cnt=0;
int dis[M],h[M],vis[M],head[M]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值