2016 Multi-University Training Contest 1 1005 Necklace

来源:互联网 发布:程序员外包 编辑:程序博客网 时间:2024/05/29 19:22

题目链接:点击打开链接

题目大意:给你一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");elseputs("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
原创粉丝点击