HDU 5727 Necklace 二分图匈牙利最大匹配,
给你阴阳球各n个,某些阳球只要周围有一个阴球,就会变暗,问最后至少要变暗多少个。
看了题解,说是全排列阴球,因为成环,所以就能变成8!复杂度,就能跑了。
然后每种情况,如果一个阳球碰上周围两个阴球都不变暗,那么久能放在这个位置,此时的最大匹配就是这种方案,最大可以放,并且不变暗的,个数。拿n一减,完事取最小值就行。就是暴力。
完事还有一个最好用的函数next......(bulabula),直接得到全排列。
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <string> #include <cstdlib> #include <vector> #include <set> #include <map> using namespace std; vector<int>e[10]; int mp[10][10]; int linker[10]; int vis[10]; int pos[10]; int dfs(int u) { for (int i=0; i<e[u].size(); i++) { int v=e[u][i]; if (!vis[v]) { vis[v]=1; if (linker[v]==-1||dfs(linker[v])) { linker[v]=u; return 1; } } } return 0; } int main() { int n,m,ans; while (scanf ("%d%d",&n,&m)!=EOF) { memset(mp,0,sizeof(mp)); while (m--) { int t1,t2; scanf ("%d%d",&t1,&t2); mp[t1][t2]=1; } if (n==0) { printf ("0\n"); } else { ans=10; for (int i=1; i<=n; i++) pos[i]=i; do { for (int i=1; i<=n; i++) e[i].clear(); for (int i=1; i<=n; i++)//加边,i是阴槽,阳 { int u=pos[i]; int v; if (i==n) v=pos[1]; else v=pos[i+1]; for (int j=1;j<=n;j++)//对于每一个阳球,阴 { if (mp[j][u]||mp[j][v]) continue;//阳阴不冲突 e[j].push_back(i);//阳球进入阴槽 } } int temp=0; memset(linker,-1,sizeof(linker)); for (int i=1; i<=n; i++)//匈牙利最大匹配 { memset(vis,0,sizeof(vis)); if (dfs(i)) temp++; } ans=min(ans,n-temp); if (ans==0) break; }while(next_permutation(pos+2,pos+n+1)); printf ("%d\n",ans); } } return 0; }