首页 > 其他分享 >Solution to AT_abc285_g Tatami

Solution to AT_abc285_g Tatami

时间:2023-07-24 14:22:16浏览次数:36  
标签:std cnt int ed flow Solution Tatami dep abc285

Statement

请用若干个 \(1 \times 1\) 和 \(1 \times 2\) 的瓷砖(可以旋转)不重叠地完全覆盖 \(H \times W\) 的长方形网格。第 \(i\) 行第 \(j\) 列的网格有字符 \(c_{i,j}\),含义如下:

  • 1:该网格只能用 \(1 \times 1\) 的瓷砖覆盖。
  • 2:该网格只能用 \(1 \times 2\) 的瓷砖覆盖。
  • ?:该网格无特殊限制。

如果存在方案可以满足上述条件,输出 Yes,否则输出 No

\(1 \leq H,W \leq 300\)。

Solution

每个格子只能被覆盖一次,考虑拆点网络流。

Conclusion

  • 设源点 \(S\),汇点 \(T\)。从 \(S\) 向入点连边,从出点向 \(T\) 连边。
  • 如果某个方格上是 \(1\),将它代表的点的入点向出点连边。
  • 如果是 \(2\),从其入点向它四连通的 \(2\) 或 \(?\) 方格的出点连边。
  • 如果是 \(?\),当作其为 \(1\) 和 \(2\) 处理。
  • 所连的边容量均为 \(1\)。

求解最大流 \(f\),若 \(f = nm\) 则有解;反之无解。

Proof

对于 \(1\) 类方格(方格上写着 \(1\),下同),求解最大流时必然有 \(1\) 的贡献。

对于一条由 \(2\) 类方格组成的链,长度为 \(n\),显然地,求解最大流必然有 \(\lfloor\frac{n}{2}\rfloor\) 的贡献。

观察到如果不是链,总可以将叶子位置的方格换到别的叶子后面去,从而转化成一条链的情况。

Code

#include <bits/stdc++.h>

struct Edge {
	int to, nxt, cap, flow;
	Edge() = default;
	Edge(int to, int nxt, int cap, int flow) : to(to), nxt(nxt), cap(cap), flow(flow) {}
};

class Graph {
public:
	int n, m;
	std::vector<Edge> ed;
	std::vector<int> head;
	int cnt;
	void add_edge(int u, int v) { ed[++cnt].to = v, ed[cnt].nxt = head[u], head[u] = cnt; }
	Graph(int n, int m) : n(n), m(m), ed(m), head(n + 1, -1), cnt(-1) {}
};

class NetworkFlow : public Graph {
private:
	const int INF = 0x3f3f3f3f;
	std::vector<int> dep;

	bool bfs(int s, int t) {
		std::queue<int> q;
		while (q.size()) q.pop();
		dep.assign(n + 1, 0);
		dep[s] = 1;
		q.push(s);
		while (q.size()) {
			int x = q.front();
			q.pop();
			for (int i = head[x]; ~i; i = ed[i].nxt) {
				if ((!dep[ed[i].to]) && (ed[i].cap > ed[i].flow)) {
					dep[ed[i].to] = dep[x] + 1;
					q.push(ed[i].to);
				}
			}
		}
		return dep[t] > 0;
	}

	int dfs(const int x, const int t, int flow) {
		if (x == t || (!flow)) return flow;
		int ret = 0;
		for (int& i = cur[x]; ~i; i = ed[i].nxt) {
			int d;
			if ((dep[ed[i].to] == dep[x] + 1) &&
				(d = dfs(ed[i].to, t, std::min(flow - ret, ed[i].cap - ed[i].flow)))) {
				ret += d;
				ed[i].flow += d;
				ed[i ^ 1].flow -= d;
				if (ret == flow) return ret;
			}
		}
		return ret;
	}

public:
	int s, t;
	std::vector<int> cur;

	NetworkFlow(int n, int m) : Graph(n + 3, m), dep(n + 3), s(n + 1), t(n + 2), cur(n + 3) {}

	void add_edge(int u, int v, int w) {
		ed[++cnt].to = v, ed[cnt].nxt = head[u], head[u] = cnt;
		ed[cnt].cap = w, ed[cnt].flow = 0;
	}

	int dinic() {
		int max_flow = 0;
		while (bfs(s, t)) {
			cur = head;
			max_flow += dfs(s, t, INF);
		}
		return max_flow;
	}
};

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

	int n, m;
	std::cin >> n >> m;
	NetworkFlow G(n * m * 2, n * m * 14);
	std::vector<std::vector<int>> a(n + 2, std::vector<int>(m + 2));

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			char x;
			std::cin >> x;
			if (x == '?')
				a[i][j] = 0;
			else if (x == '1')
				a[i][j] = 1;
			else
				a[i][j] = 2;
		}
	}

	auto valid = [&a, n, m](int x, int y) {
		return x >= 1 && x <= n && y >= 1 && y <= m && (a[x][y] == 2 || a[x][y] == 0);
	};
	auto convert = [n, m](int x, int y, bool f) { return (x - 1) * m + y + f * n * m; };

	int dx[4] = {-1, 1, 0, 0};
	int dy[4] = {0, 0, -1, 1};

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			G.add_edge(G.s, convert(i, j, 0), 1);
			G.add_edge(convert(i, j, 0), G.s, 0);
			G.add_edge(convert(i, j, 1), G.t, 1);
			G.add_edge(G.t, convert(i, j, 1), 0);
		}
	}

	for (int i = 1; i <= n; ++i) {
		for (int j = 1; j <= m; ++j) {
			if (a[i][j] == 1 || a[i][j] == 0) {
				G.add_edge(convert(i, j, 0), convert(i, j, 1), 1);
				G.add_edge(convert(i, j, 1), convert(i, j, 0), 0);
			}
			if (a[i][j] == 2 || a[i][j] == 0) {
				for (int k = 0; k < 4; ++k) {
					if (!valid(i + dx[k], j + dy[k])) continue;
					G.add_edge(convert(i, j, 0), convert(i + dx[k], j + dy[k], 1), 1);
					G.add_edge(convert(i + dx[k], j + dy[k], 1), convert(i, j, 0), 0);
				}
			}
		}
	}

	int max_flow = G.dinic();
	std::cerr << max_flow << '\n';
	if (max_flow == n * m)
		std::cout << "Yes" << '\n';
	else
		std::cout << "No" << '\n';
	return 0;
}

标签:std,cnt,int,ed,flow,Solution,Tatami,dep,abc285
From: https://www.cnblogs.com/escap1st/p/17577103.html

相关文章

  • [SOLVED] 终端下screenfetch返回 Resolution: No X Server
    "Linux图形界面多数使用的是XServer,我们有时需要关闭/重启它.比如:安装NVIDIA的驱动程序时,就需要先关闭Xserver;希望让系统以server方式运行,关闭桌面环境以降低不必要的性能损耗."[1] 检查图形界面XServer的状态:systemctlstatuslightdm.service显示了li......
  • AT_abc251_g Intersection of Polygons Solution
    AT_abc251_gIntersectionofPolygonsSolutionPreface由于某些\(\LaTeX\)的原因,本文的公式无法正常查看,建议读者访问博客以获得正常阅读体验。Statement逆时针地给定一个有\(N\)个顶点,第\(i\)个顶点为\((x_i,y_i)\)的凸包\(P_0\)。再给出\(M\)个向量\((u_i,v......
  • IPQ5018 SoC with QCN9074 VS QCN6122|IIOT Wifi6 solution|Wallys
    IPQ5018SoCwithQCN9074VSQCN6122|IIOTWifi6solution|WallysIntheeraofIndustry4.0,reliableandefficientwirelessconnectivityiscrucialforindustrialandenterpriseapplications. That'swhereWallyscomesinwithourcutting-edgeCost-Effe......
  • Solution Set of NFLS SImulations
    在nfls的最后一天,来记录一些似乎有意义的题吧。没有原题(或者我忘了原题)的就简要写下题意,不放原题面了。目录T2(CF1329EDreamoonLovesAA)T1(CF1184D2ParallelUniverses(Hard))T3(CF1434EAConvexGame)T1怪兽(树上MonsterHunting)T2切割T3导弹T1(CF1023GPisc......
  • 【论文解析】EJOR 2011 A clustering procedure for reducing the number of represen
    论文名称:AclusteringprocedureforreducingthenumberofrepresentativesolutionsintheParetoFrontofmultiobjectiveoptimizationproblems动机假设一个三目标优化问题\[\begin{aligned}&\text{Availability:}\max_\thetaJ_1(\theta)=\max_{\theta_p,......
  • Solution Set - 2023 省队集训
    2023-7-8模拟赛铁路(railway)Source:ROI2017D1T4C国有\(n\)个城市与\(m\)条铁路线,铁路均为单向,第\(i\)号铁路线被从起点到终点的\((s_i+1)\)个城市\(c_{i,1},c_{i,2},\cdots,c_{i,s_i+1}\)分为\(s\)段,从\(c_{i,j}\)乘铁路到\(c_{i,j+1}\)......
  • Solution Set - “女孩是瑰宝我心动一丝不苟”
    目录0.「NOISimu.」静态顶树⭐1.「NOISimu.」祖先2.「NOISimu.」睡眠⭐3.「JLOI2008」「洛谷P3881」CODES4.「ARC163A」DivideString5.「ARC163B」FavoriteGame6.「ARC163C」HarmoniceMean⭐7.「ARC163D」SumofSCC8.「NOISimu.」国王的旅行⭐9.「NOISimu.」图......
  • 「Solution Set」7/4
    「SDOI/SXOI2022」无处存储链加链求和。考虑先搞出随机撒点,然后建虚树,这样比较好维护一点。然后就是正常的整块打tag,散块暴力加之类的。我写的好麻烦/kk「LibreOJRound#11」MisakaNetwork与Accelerator我们考虑暴力2-SAT,最多要连\(O(n^2)\)条边,时间空间都接受不......
  • 「Solution Set」7/3
    P4433[COCI2009-2010#1]ALADIN我们发现就是区间加一个等差数列,但是要取模后的。我们考虑加一个首项为\(A\),公差为\(B\),项数为\(n\)的等差数列,还要对\(C\)取模。那么和就是这样的:\(\sum\limits_{i=0}^{n-1}Bi+A-\lfloor\frac{Bi+A}{C}\rfloor\timesC\)然后前面两......
  • Solution Set - “如果惊蛰随梦远走”
    目录0.「UR#15」「UOJ#226」奥林匹克环城马拉松⭐1.「UR#22」「UOJ#682」月球铁轨⭐2.「NOISimu.」箭头3.「CF830E」PerpetualMotionMachine⭐4.「CF1474F」1234…⭐5.「CF1842H」TenzingandRandomRealNumbers6.「UR#17」「UOJ#370」滑稽树上滑稽果7.「SD......