2016 Multi-University Training Contest 1 1005 Necklace

题目链接:点击打开链接

题目大意:给你一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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值