HDU 5727 Necklace

枚举环排列+二分图匹配计算答案。

可以枚举一下yin的排列方式,因为是环,所以可以固定一个,剩下的8个进行全排列。

对于每一个全排列,会产生n个位置供yang放置,如果某位置放置某yang不会使该yang褪色,则该位置向该yang连边。

然后跑一次二分图最大匹配,即可得到在yin这样的排列方式下,最多有多少yang不会褪色,更新一下答案。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<iostream>
using namespace std;
typedef long long LL;

const int maxn=12;
int n,m,nx,ny;
int g[maxn][maxn],cx[maxn],cy[maxn],mk[maxn];
bool f[maxn][maxn];
int p[maxn];

int path(int u)
{
    for(int v=0; v<ny; v++)
    {
        if(g[u][v]&&!mk[v])
        {
            mk[v]=1;
            if(cy[v]==-1||path(cy[v]))
                { cx[u]=v,cy[v]=u; return 1; }
        }
    }
    return 0;
}

int MaxMatch()
{
    int res=0;
    memset(cx,-1,sizeof(cx));
    memset(cy,-1,sizeof(cy));
    for(int i=0; i<nx; i++)
    {
        if(cx[i]==-1)
        {
            memset(mk,0,sizeof(mk));
            res=res+path(i);
        }
    }
    return res;
}

int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(f,0,sizeof f);
        for(int i=1;i<=m;i++)
        {
            int u,v; scanf("%d%d",&u,&v);
            f[u][v]=1;
        }

        if(n==0) {printf("0\n"); continue;}

        int ans=0x7fffffff;
        for(int i=1;i<=n;i++) p[i]=i; nx=ny=n;
        do
        {
            memset(g,0,sizeof g);
            for(int i=1;i<=n;i++)
            {
                for(int j=0;j<n;j++)
                {
                    if(j==0&&f[i][p[n]]==0&&f[i][p[1]]==0) g[j][i-1]=1;
                    else if(j!=0&&f[i][p[j]]==0&&f[i][p[j+1]]==0) g[j][i-1]=1;
                }
            }
            ans=min(ans,n-MaxMatch());
        }while(next_permutation(p+1,p+n)&&ans);
        printf("%d\n",ans);
    }
    return 0;
}
//.

 

posted @ 2016-07-21 22:23  Fighting_Heart  阅读(297)  评论(0编辑  收藏  举报