hdu 5727 Necklace

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<<'
';
    }
}
原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/8306737.html