题目链接:点击打开链接
题目大意:给你一2*n个珠子,n个阳珠子,n个阴珠子,另外有m中情况,当a号阳珠子和b号阴珠子在一起的时候会变暗,求变暗的最小数量。
解题思路:(官方题解先放一边,估计函数什么的我真不太懂)做法就是全排列一种珠子的情况,然后尝试着尽可能的放入阳珠子,找出最多能放多少就好。
重点在dfs的设计,这种设计我也是第一次看见,不得不说脑洞好大,当你找到一个位置的时候,它是合法位置的要求是:他左边没有点(或者右边因为是环,所以定好一个方向即可)或者是它左边的点可以找到一个合适的新位置。
代码:
#include<iostream>
#include<vector>
#include<cmath>
#include<algorithm>
#include<ctime>
#include "cstdio"
#include "string"
#include "string.h"
#include "map"
using namespace std;
bool change[15][15],G[15][15];
int n, m, a[15];
int edge[15], vis[15];
bool dfs(int u)
{
for (int v = 1;v <= n;v++)
{
if (vis[v] == 0 && G[u][v])
{
vis[v] = 1;
if (edge[v] == -1 || dfs(edge[v]))
{
edge[v] = u;
return true;
}
}
}
return false;
}
int solve()
{
int ans = 0;
memset(edge, -1, sizeof(edge));
for (int i = 1;i <= n;i++)
{
memset(vis, 0, sizeof(vis));
if (dfs(i))
ans++;
}
return ans;
}
int main()
{
while (scanf("%d %d", &n, &m) != EOF)
{
memset(change, true, sizeof(change));
for (int i = 0;i < m;i++)
{
int x, y;
scanf("%d %d", &x, &y);
change[x][y] = false;
}
if (n == 0)
{
puts("0");
continue;
}
if (n == 1)
{
if (change[1][1])
puts("0");
else
puts("1");
continue;
}
for (int i = 1;i <= n;i++)
a[i] = i;
int ans = -1;
do {
memset(G, false, sizeof(G));
for (int i = 1;i <= n;i++)
{
for (int j = 1;j <= n;j++)
{
int next = j == n ? 1 : j + 1;
if (change[i][a[j]] && change[i][a[next]])
G[i][j] = true;
}
}
ans = max(ans, solve());
} while (next_permutation(a + 2, a + n + 1));
printf("%d\n", n - ans);
}
return 0;
}