首页 > 其他分享 >UVA1514 Piece it together 题解

UVA1514 Piece it together 题解

时间:2023-05-25 21:58:35浏览次数:55  
标签:cnt UVA1514 题解 int black mp && 黑点 Piece

图论题还是在于建图

题意

给定一个长度为 \(n \times m\) 的网格图,有的地方是白方块,有的是黑方块,有的啥也没用。

给你如下四种 \(L\) 形方块,询问是否存在方法,让这些方块正好就是给出的图的形状。

$ L $ 形方块如下

思路

二分图

  • 首先我们要想,为什么需要二分图:

    若能拼成,那么就说明白块的数量,刚好是黑块数量的两倍,因为黑块和白块互相独立,所以我们就可以应用二分图的思想进行匹配。

  • 再次,我们想怎么建图

    如果只用一个黑点匹配,那么我们不可能向四个方向连边,这样我们就不能确保最后的形状是 $ L $ 形的。

    怎么办呢?

    把同一个黑块分裂成两个!但是为了确保是 $ L $ 形的,我们让一个黑点连上下,一个黑点连左右的白点。至此,整个题的思路就出来了:

  1. 首先统计白点和黑点的数量,给每个黑点和白点编号。统计完后,如果原图中白块数量不是黑块数量的两倍,说明怎么配肯定配不出来;

  2. 再循环一次,让黑点跟白点连边;

  3. 二分图匹配,如果匹配数等于白点数,说明成功。

代码实现

#include<bits/stdc++.h>
//#define int long long
#define ll long long
#define next nxt
#define il inline
const int M = 2e5 + 5;
const int P = 1e4 + 5;
const int N = 5e2 + 5;
using namespace std;
int max(int x,int y) { return x > y ? x : y; }
int min(int x,int y) { return x < y ? x : y; }

struct node {
	int u,v,next;
} edge[M << 2]; int head[P],num_edge;
int match[P],vis[P],cnt[N][N],black,white;
int ans,n,m,e,u,v,T;
char mp[N][N];

il int read() 
{
	int f=0,s=0;
	char ch=getchar();
	for(; !isdigit(ch); ch=getchar()) f |= (ch=='-');
	for(; isdigit(ch); ch=getchar()) s = (s<<1) + (s<<3) + (ch^48);
	return f ? -s : s;
}

il void add(int from,int to) 
{
	edge[++num_edge].u = from;
	edge[num_edge].v = to;
	edge[num_edge].next = head[from];
	head[from] = num_edge;
}

il bool dfs(int u) 
{
	for(int i=head[u]; i; i=edge[i].next) 
	{
		int v = edge[i].v;
		if(vis[v]) continue;
		vis[v] = 1;
		if(!match[v] || dfs(match[v])) 
		{
			match[v] = u;
			return true;
		}
	}
	return false;/*匈牙利板子*/
}

int main() 
{
	T = read();
	while(T--) 
	{
		memset(head , 0 , sizeof head);
		memset(match , 0 , sizeof match);
		num_edge = 0 , black = 0 , white = 0 , ans = 0;
		n = read() , m = read();
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++) 
			{
				cin >> mp[i][j];
				if(mp[i][j] == 'B') cnt[i][j] = ++black;/*给每个黑白点编号*/
				if(mp[i][j] == 'W') cnt[i][j] = ++white;
			}
		if(black == 0 && white == 0) { puts("YES");/*黑点白点都没有直接不放就行了*/ continue; }
		if(black*2 != white) { puts("NO");/*如果本身就不匹配,那么说明肯定不行*/ continue; }
		for(int i=1; i<=n; i++)
			for(int j=1; j<=m; j++)
				if(mp[i][j] == 'B') 
				{
					if(i > 1 && mp[i-1][j] == 'W') add(cnt[i][j],cnt[i-1][j]);/*一个黑点分成两个点*/
					if(i < n && mp[i+1][j] == 'W') add(cnt[i][j],cnt[i+1][j]);/*连上下*/
					if(j > 1 && mp[i][j-1] == 'W') add(cnt[i][j]+black,cnt[i][j-1]);/*分裂后的黑点连左右*/
					if(j < m && mp[i][j+1] == 'W') add(cnt[i][j]+black,cnt[i][j+1]);
				}/*二分图跑匹配*/
		black*=2;/*黑点的数量要乘以二*/
		for(int i=1; i<=black; i++) 
		{
			memset(vis , 0 , sizeof vis);
			if(dfs(i)) ans++;
			else break;
		}
		if(ans == white) puts("YES");/*能匹配完,说明可以*/
		else puts("NO");
	}
	return 0;
}

复杂度 $ O(TnE) $ 可以通过。

这题也可以跑 dinic 网络流,复杂度可以更优,用二分图匹配做另一个 SP9890 同样的题,时限小了,过不去,只能跑网络流。

标签:cnt,UVA1514,题解,int,black,mp,&&,黑点,Piece
From: https://www.cnblogs.com/bloodstalk/p/17433066.html

相关文章

  • SP15637 Mr Youngs Picture Permutations 题解
    题意给定一个最多有\(5\)排的一个队伍,每一个位置对应一个同学,给定总人数和第\(i\)排要站\(n_i\)个人。要求每行左边的同学身高要大于右边的,每列从上往下要从大到小。问:满足要求的一共有多少种方案。思路DP首先考虑,在这个题目中,有用的状态有每列最后的人的高度,每行......
  • P8584 探索未知 题解
    题意给你\(n\)个分数,每个分数后面跟着一个操作符\(op\),如果为\(1\)就是加上这个分数,是\(2\)就减去。初始时是\(0\),询问\(n\)次操作后最后的分数是多少,化成最简分数。特殊地,如果最后是个整数,直接以整数的形式输出。思路模拟考试的时候一看就想到了[NOIP2020]......
  • P8587 新的家乡 题解
    题意给定\(n\)个高度分别为\(h_i\)的柱子,两个柱子能合并成一个\(h_i+h_j\)的新柱子,每根柱子至多被使用一次。询问最多能建出多少根高度相同的柱子,并且最优答案下柱子的高度有多少种情况。\(1\leqn\leq10^6\),\(1\leqh_i\leq3\times10^3\)。思路爆搜!首先我们......
  • P8585 球状精灵的传说 题解
    很好的一个题题意给你\(n\)个三元组\((r_1,r_2,r_3)\),并定义\(ρ=\lfloor\frac{1}{4}min(r_1,r_2,r_3)^3\rfloor\)。两个三元组能合并当且仅当这两个三元组有至少两个值相同,即从\((x_1,y,z)\)和\((x_2,y,z)\)变为\((x_1+x_2,y,z)\)。\((x,y,z)\)的位置不固定......
  • Android 修改 android/hardware/interfaces 下HIDL接口编译报异常问题解决
    最近要增加hostapd的一个HIDL接口,修改android/hardware/interfaces/wifi/hostapd/1.2/IHostapd.hal文件后编译报错如下:ERROR:[email protected]::IHostapdhashashacaed0a159a521bd4964e0fb8117320849109d3eeaff6a08b4d2506156ce6987whichdoesnotmatch......
  • P2480 古代猪文 题解
    题意:求\[g^{\sum_{k\midn}{n\choosek}}\]对\(999911659\)取模。\(1\len,g\le10^9\)。思路:首先根据欧拉定理,题目转化为求\(\displaystyle\sum_{k\midn}{n\choosek}\)对\(999911658\)取模的值。模数为合数不是很好做,因式分解发现\(999911658=2\times3\times467......
  • JOISC 2021 题解
    JOISC21フードコート(FoodCourt)首先我们发现我们这个删除实际上可以假删除,我们每次问询时求出这个队列目前被删了几个(维护区间加,区间\(\max(0,A-x)\))就可以把删除操作给弄掉了。然后我们考虑对商店做扫描线!因为我们现在其实就是对商店的单点问询,我们这个加入操作也可以在左......
  • 【题解】Codeforces Round 737 (CF1557)
    VP情况:solve:4/5rank:431st评价:VP了一下,我这个shaberB直接5发罚时,耽误了二十多分钟,以及被D各种细节差点搞死。A.EzzatandTwoSubsequences(*800)题目描述:给定一个序列,将其分为\(2\)个组,要求这两个组的平均值之和最大,组内的数不要求在原序列中连续。题目分析:我们......
  • 【题解】CF1062E Company
    传送门先考虑如何求解区间LCA假设要我们求\(8\sim11\)的LCA。那么显然它们的LCA等效于8和11的LCA。发现8和11刚好是“最左”和“最右”的两个顶点,感性理解一下,就可以得出一个结论:区间LCA和dfs序最小的和最大的的LCA是等效的。(这个结论应该还......
  • 题解(教主的魔法)P2801
    题目教主的魔法题目描述教主最近学会了一种神奇的魔法,能够使人长高。于是他准备演示给XMYZ信息组每个英雄看。于是$N$个英雄们又一次聚集在了一起,这次他们排成了一列,被编号为$1,2,\ldots,N$。每个人的身高一开始都是不超过$1000$的正整数。教主的魔法每次可以把闭区......