#include <stdio.h>
#include <string.h>
#define DEBUG
#ifdef DEBUG
#define debug(...) printf( __VA_ARGS__)
#else
#define debug(...)
#endif
#define N 301
char weight[101][N]; /* weight[x][y] = 1 表示学生x可以做课程y的助教 */
char mat[N]; /* mat[y] = x,表示定点y和x匹配 */
char visit[N];
int nx, ny;
int find(int x)
{
int y;
debug("go to X.%d\n", x);
for (y = 1; y <= ny; y++) {
if (!visit[y] && weight[x][y] > 0) {
debug("go to Y.%d\n", y);
visit[y] = 1;
if (mat[y] == -1 || find(mat[y])) {
debug("%d %d %d\n", x, y, mat[y]);
/* 事实上程序实现的时候不用取反操作来标记哪些边已加入M,哪些边未加入M
* 因为由mat数组和visit数组就可以确定,若mat[y] != -1, 则(mat[y],y)必然是一条加入M的边
* 只要visit[y] = 0,则(x,y)必然是一条没有加入M的边
if (mat[y] != -1) {
weight[mat[y]][y] *= -1;
}
weight[x][y] *= -1;
*/
mat[y] = x;
return 1;
}
debug("return from Y.%d\n", y);
}
}
return 0;
}
int main()
{
int t, m, x, y, possible;
scanf("%d", &t);
while (t--) {
memset(weight, 0, sizeof(weight));
memset(mat, -1, sizeof(mat));
scanf("%d %d", &nx, &ny); /* X集合是课程,Y集合是学生, 课程应比学生少 */
for (x = 1; x <= nx; x++) {
scanf("%d", &m);
while (m--) {
scanf("%d", &y);
weight[x][y] = 1;
}
}
if (nx > ny) {
printf("NO\n"); continue;
}
possible = 1;
for (x = 1; x <= nx; x++) {
memset(visit, 0, sizeof(visit));
if (!find(x)) { /* X集合只要有一个定点找不到增广路径,则图必然不是完备匹配 */
possible = 0;
break;
}
debug("got an augmenting path...\n");
}
if (possible) {
printf("YES\n");
}
else {
printf("NO\n");
}
}
return 0;
}
poj 1469 匈牙利算法求最大匹配
最新推荐文章于 2020-03-04 22:28:03 发布
本文介绍了一种基于匈牙利算法解决二分图最大匹配问题的方法。通过详细讲解算法流程和提供具体C语言代码实现,帮助读者理解如何利用匈牙利算法寻找二分图中的最大匹配。特别适用于课程安排等实际应用场景。

1468

被折叠的 条评论
为什么被折叠?



