http://acm.hdu.edu.cn/showproblem.php?pid=5727
阶乘 爆搜阴性宝石的排列,二分图最大匹配判断最多能使多少个阳性宝石不褪色
注:
1、O(n-1 !) 即可
2、dfs枚举全排列下一个放啥,是阶乘再乘n级别,用next_permutation阶乘复杂度
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int n,m; bool somber[10][10]; int tmp[11]; bool use[10]; bool map[10][10],vis[10]; int match[10]; int ans; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar(); } } bool go(int u) { for(int i=1;i<=n;++i) { if(!map[u][i] || vis[i]) continue; vis[i]=true; if(!match[i] || go(match[i])) { match[i]=u; return true; } } return false; } void judge() { tmp[n+1]=1; memset(map,true,sizeof(map)); memset(match,0,sizeof(match)); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) if(somber[tmp[j]][tmp[i]] || somber[tmp[j]][tmp[i+1]]) map[i][j]=false; int now=n; for(int i=1;i<=n;++i) { memset(vis,false,sizeof(vis)); if(go(i)) now--; } ans=min(ans,now); } void work(int x) { for(int i=1;i<=n;++i) tmp[i]=i; do { judge(); }while(next_permutation(tmp+2,tmp+n+1)); } int main() { int a,b; while(scanf("%d",&n)!=EOF) { memset(somber,false,sizeof(somber)); read(m); while(m--) { read(a); read(b); somber[a][b]=true; } if(!n || !m) { puts("0"); continue; } ans=n; work(1); cout<<ans<<‘\n‘; } }