「2016山东省队集训」 分子切割 molecule
来源:互联网 发布:淘宝开店店铺简介 编辑:程序博客网 时间:2024/05/22 08:18
Description
Sample Input & Output
HINT
Solution
记录一下这道题,网络流建模好题!
首先不考虑1,那么答案就是每个L形两个2最大匹配是多少。
因为一个1只能用一次,因此我们把这个二分图连的边拆开。不能同时用的一对2都连到一个1的点上,然后把这个点拆开,加流量为1的限制即可。
考试的时候写了个类似于匈牙利的玩意,结果TLE+WA。越来越弱了。。。。连网络流也想不出来了。。。
然后1拆点还加了4条边,简直药丸。。。
Code
#include <cstdio>#include <cstring>#include <algorithm>using namespace std;typedef long long LL;const int INF = 1009999999;const int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};struct edge_type { int to, next, r;} edge[500005];int S, T, cnte = 1, h[500005];int Q[500005];void ins(int u, int v, int f) { ++cnte; edge[cnte].to = v; edge[cnte].r = f; edge[cnte].next = h[u]; h[u] = cnte; ++cnte; edge[cnte].to = u; edge[cnte].r = 0; edge[cnte].next = h[v]; h[v] = cnte;}int tail, head, d[500005], cur[500005];bool bfs() { tail = head = 0; for (int i = S; i <= T; ++i) d[i] = -1; Q[tail++] = S; d[S] = 0; int now; while (head < tail) { now = Q[head++]; for (int i = h[now]; i; i = edge[i].next) { if (d[edge[i].to] == -1 && edge[i].r) { d[edge[i].to] = d[now] + 1; Q[tail++] = edge[i].to; } } } return d[T] != -1;}int dfs(int now, int a) { if (T == now || a == 0) return a; int ret = 0, f; for (int &i = cur[now]; i; i = edge[i].next) { if (d[edge[i].to] != d[now]+1) continue; if (f = dfs(edge[i].to, min(a, edge[i].r))) { a -= f; ret += f; edge[i].r -= f; edge[i^1].r += f; if (a == 0) break; } } if (ret == 0) d[now] = -1; return ret;}int Dinic() { int ret = 0; while (bfs()) { for (int i = S; i <= T; ++i) cur[i] = h[i]; ret += dfs(S, INF); } return ret;}int a[510][510], id[510][510], id2[510][510], n, m, tot;int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { scanf("%d", &a[i][j]); id[i][j] = ++tot; if (a[i][j] == 1) id2[i][j] = ++tot; } for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) if (a[i][j] == 1) { ins(id[i][j], id2[i][j], 1); for (int k = 0; k < 4; ++k) { int tx1 = i + dx[k], ty1 = j + dy[k], tx2 = i + dx[(k+1)%4], ty2 = j + dy[(k+1)%4]; if (1 <= tx1 && tx1 <= n && 1 <= tx2 && tx2 <= n && 1 <= ty1 && ty1 <= m && 1 <= ty2 && ty2 <= m) if (a[tx1][ty1] == 2 && a[tx2][ty2] == 2) { if (tx1 & 1) ins(id[tx1][ty1], id[i][j], 1), ins(id2[i][j], id[tx2][ty2], 1); else ins(id[tx2][ty2], id[i][j], 1), ins(id2[i][j], id[tx1][ty1], 1); } } } S = 0; T = ++tot; for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j) { if (a[i][j] == 2) { if (i & 1) ins(S, id[i][j], 1); else ins(id[i][j], T, 1); } } int ans = Dinic(); printf("%d", ans); return 0;}
0 0
- 「2016山东省队集训」 分子切割 molecule
- 「2016山东省队集训」 LYK loves jumping
- 「2016山东省队集训」 Play with array
- 「2016山东省队集训」 线段树学习之标记永久化
- 「2016湖南集训」 猜测 guess
- 2016山东省赛总结
- 山东省
- 2016山东省赛H题
- [莫队维护DP] LOJ#6074. 「2017 山东一轮集训 Day6」子序列
- 使用 MOLECULE 迅速包装百度 UEditor
- Rust: codewars的Molecule to atoms
- 分子公司
- 分子计算机
- 分子设计
- 极性分子
- 分子计算机
- 省队集训 water
- 省队集训DAY2
- 使用eclipse远程hive时出现的错误大汇总
- 孙宇教授解读:美国国家机器人计划2.0——无处不在的协作机器人
- shell 脚本各种执行方式(source ./*.sh, . ./*.sh, ./*.sh)的区别
- MATLAB读取不同行列的txt格式文件
- 程序设计实训报告 项目3.2
- 「2016山东省队集训」 分子切割 molecule
- 如何评价微软在其数据中心大量部署FPGA?
- c++运算符重载总结
- -vmargs -Xmx512m -XX:MaxPermSize=256m -XX:ReservedCodeCacheSize=64m
- Eclipse下导入外部jar包的3种方式
- Python datetime模块之date
- vector的基础语法
- vsphere打开虚机半天后没有反应
- 微信小程序(一):微信小程序申请注册与开发流程