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;
}

 

posted on 2016-07-20 22:54  very_czy  阅读(287)  评论(0编辑  收藏  举报

导航