您的位置:首页 > 其它

CodeForces Gym 100735G 二分图匹配

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

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

还是说下方法吧,字符串的每个字符为左边的点,每个 正方体为右边的 点,然后对于坐标的字符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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: