CodeForces Gym 100735G 二分图匹配

就是给你一个字符串,和一些正方体,每个正方体的六个面上都标有字母或者数字,然后问你能否选一些正方体,通过某种摆放,使得他们摆成一排后组成的那个字符串

据说是裸的二分图匹配,但是我这种智障就是没看出裸来啊,果然图论题做的太少太少,然后看别人代码又短又快,总以为是暴力,然后题意也没说这些正方体可以怎么操作,迷的一笔

还是说下方法吧,字符串的每个字符为左边的点,每个 正方体为右边的 点,然后对于坐标的字符i,如果右边的正方体j上有一个面和它相等,就连边 ,然后建好图之后跑二分图匹配就行,如果匹配数等于字符串字符个数,就是YES否则就是NO

#include <cstdio>
#include <cstring>
#include <vector>
#include <iostream>
#include <string>
#include <cmath>
#include <algorithm>
#include <set>
#include <map>
using namespace std;
#define maxn 25
#define maxm 105
char s0[25];
int N, M;
int len;
int n;
char cube[105][8];
bool graph[maxn][maxm];
bool vis[maxm];
int match[maxm];
bool find(int x)
{
	int j;
	for (j = 0; j < M; j++)
	{
		if (graph[x][j] == true && vis[j] == false)
		{
			vis[j] = true;
			if (match[j] == -1 || find(match[j]))
			{
				match[j] = x;
				return true;
			}
		}
	}
	return false;
}
int main()
{
	//freopen("input.txt", "r", stdin);
	scanf("%s%d", s0, &n);
	len = strlen(s0);
	char ch;
	for (int i = 0; i < n; ++i)
	{
		for (int j = 0; j < 6; ++j)
		{
			while (ch = getchar())
			{
				if ((ch >= 'a'&&ch <= 'z') || (ch >= '0'&&ch <= '9'))
				{
					cube[i][j] = ch;
					break;
				}
			}
		}
	}
	N = len; M = n;
	for (int i = 0; i < len; ++i)
	{
		for (int j = 0; j < n; ++j)
		{
			for (int k = 0; k < 6; ++k)
			{
				if (s0[i] == cube[j][k])
				{
					graph[i][j] = true;
					break;
				}
			}
		}
	}
	/*for (int i = 0; i < N; ++i)
	{
		for (int j = 0; j < M; ++j)
		{
			printf("%d ", graph[i][j]);
		}
		printf("\n");
	}*/
	memset(match, -1, sizeof(match));
	int ans = 0;
	for (int i = 0; i < N; i++)
	{
		memset(vis, 0, sizeof(vis));
		if (find(i)) ans += 1;
	}
	//printf("ans %d\n", ans);
	if (ans == len)
		printf("YES\n");
	else
		printf("NO\n");
	//system("pause");
	//while (1);
	return 0;
}

### Codeforces 平台上的二分图染色算法题目 #### CF1949I. Disks 的解题思路 对于给定的一组圆盘,判断是否存在一种方式使得这些圆盘能够通过改变大小来满足特定条件。如果存在某个圆既变小又变大,或者变小的圆的数量不等于变大的圆的数量,则该连通块无法实现目标状态[^5]。 为了验证这一点,可以采用二分图染色的方法: - 将每个圆视为图中的节点; - 如果两个圆之间有交集,则在这两个节点间建立一条边; - 使用两种不同的颜色尝试对整个图形进行着色,在此过程中遇到冲突则说明不存在合法方案; 这种方法不仅适用于本题描述的情况,也广泛应用于其他涉及二分性质的问题求解中。 #### 构造性算法实例 在解决一些具有构造特性的编程挑战时,比如构建IP地址这样的任务[T1 IP地址(ip)][^2],虽然这并不是典型的二分图问题,但是当涉及到如何有效地分配资源(如同一网络内的设备编号),也可以借鉴类似的思维模式——即合理规划不同部分之间的关系以达到最优配置效果。 ```cpp // C++ code snippet demonstrating bipartite graph coloring approach #include <bits/stdc++.h> using namespace std; const int MAXN = 1e5 + 7; int color[MAXN]; vector<int> adj[MAXN]; bool dfs(int u, int c) { color[u] = c; for (auto v : adj[u]) { if (!color[v]) { if (!dfs(v, 3 - c)) return false; // alternate colors between 1 and 2 } else if (color[v] == c) return false; // found an odd cycle or conflict } return true; } void solve() { memset(color, 0, sizeof(color)); bool isBipartite = true; for (int i = 1; i <= n && isBipartite; ++i) { if (!color[i]) isBipartite &= dfs(i, 1); } cout << (isBipartite ? "YES\n" : "NO\n"); } ``` 上述代码展示了利用深度优先搜索(DFS)来进行二分图检测的过程。这里假设输入已经准备好了一个无向图的数据结构`adj[]`表示邻接表形式存储的图以及顶点数量n。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值