标签:
题意:( 0 <= n <= 9 )
现在有n颗阴珠子和n颗阳珠子,将它们阴阳相间圆排列构成一个环,
已知有些阴珠子和阳珠子不能放在相邻的位置,否则这颗阳珠子就会失去功效,
输出最少失去能量的阳珠子数目
分析: 枚举 + 二分图匹配
先把阴珠放好,然后将阳珠插入空位中。
枚举阴珠摆放位置,将阳珠匹配到不影响两边阴珠的位置
这样 ans = min( n - 最大匹配数 )
注意:
n = 0 时 无法使用 next_permutation 函数!!
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int MAXN=20; 6 int n, m, ans; 7 bool G[MAXN][MAXN], F[MAXN][MAXN], used[MAXN]; 8 int Linker[MAXN]; 9 int a[MAXN]; 10 bool dfs(int u) 11 { 12 for(int v = 1;v <= n; v++) { 13 if(G[u][v] && !used[v]) { 14 used[v] = 1; 15 if(Linker[v]==-1||dfs(Linker[v])) { 16 Linker[v] = u; 17 return 1; 18 } 19 } 20 } 21 return 0; 22 } 23 int Hungary(){//匈牙利 24 int res = 0; 25 memset(Linker, -1, sizeof(Linker)); 26 for(int u = 1; u <= n; u++){ 27 memset(used, 0, sizeof(used)); 28 if(dfs(u)) res++; 29 } 30 return res; 31 } 32 int main() 33 { 34 while(~scanf("%d%d",&n,&m)) 35 { 36 memset(F,0,sizeof(F)); 37 for(int i=1;i<=m;i++) 38 { 39 int a,b; 40 scanf("%d%d",&a,&b); 41 F[a][b]=1; 42 } 43 ans=100; 44 for(int i=1;i<=n;i++) a[i]=i; 45 if(n == 0) { puts("0"); continue; }//此时无法全排列!!! 46 do//全排列 47 { 48 memset(G,0,sizeof(G)); 49 for(int i = 1;i <= n;i++) 50 { 51 int l = a[i],r = (i == n ? a[1] : a[i+1]); 52 for(int u = 1;u <= n; u++) 53 if( !F[u][l] && !F[u][r])//不影响两边 54 G[u][i]=1; 55 } 56 ans=min(n - Hungary(), ans); 57 } while (next_permutation(a + 2,a + n + 1));//因为是环,第一点不用动 58 printf("%d\n",ans); 59 } 60 }
标签:
原文地址:http://www.cnblogs.com/nicetomeetu/p/5701988.html