给定n个阴n个阳,按照阴阳的顺序排列问变暗的最少有几个
首先想到的是二分图,因为阴阳很符合二分图的性质。但是很快又把自己否定了,因为前几天的一场 CF有一题是安排时间是去体育馆还是学习的题目当时也觉得是二分图但是搞到结束都没有写出来。所以又感觉这题不是二分图了。。
看了题解,因为只有八个点 ,所以做一次二分图的速度非常快,所以枚举位置9!。对于每种情况做一次二分图匹配,时间复杂度居然也意外的合理。。。。
因为是首尾相连所以可以只枚举8个位置
#include <iostream>
#include <cstdio>
#include <cstring>
#include <string.h>
#include <string>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <sstream>
#include <cstdlib>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define sp system("pause")
vector<int>g[15];
int gg[15][15];
int linker[10];
bool vis[10];
int pos[10];
int n;
bool dfs(int u)
{
for (int i = 0; i < g[u].size(); i++)
{
int v = g[u][i];
if (!vis[v])
{
vis[v] = true;
if (linker[v] == -1 || dfs(linker[v]))
{
linker[v] = u; return true;
}
}
}
return false;
}
int solve()
{
int res = 0;
memset(linker, -1, sizeof linker);
for (int i = 1; i <= n; i++)
{
memset(vis, false, sizeof vis);
if (dfs(i))res++;
}
return res;
}
int main()
{
int m;
while (cin >> n >> m)
{
memset(gg, 0, sizeof gg);
for (int i = 0; i < m; i++)
{
int x, y;
scanf("%d%d", &x, &y);
gg[x][y] = 1;
}
if (n == 0)
{
puts("0");
continue;
}
int ans = 10;
for (int i = 0; i < n; i++)pos[i] = i + 1;
do
{
for (int i = 0; i <= n; i++)g[i].clear();
for (int i = 0; i < n; i++)
{
int x = pos[i], y = pos[(i + 1) % n];
for (int j = 1; j <= n; j++)
if (!gg[j][x] && !gg[j][y])g[j].push_back(i + 1);
}
ans = min(ans, n - solve());
if (!ans)break;
} while (next_permutation(pos+1, pos + n));
printf("%d\n", ans);
}
}