hdoj 5727 Necklace 二分图 全排列

来源:互联网 发布:sqlserver 视图概念 编辑:程序博客网 时间:2024/06/05 18:32

因为是个串,先全排列n个阴珠子的顺序 (n-1)!种因为编号1可以固定在头部因为是个串
然后每种排列后记录n个阳珠子是否能插进n个间隙的信息 也就是每个珠子是否能和哪个间隙匹配,然后求最大匹配,囧~~~~`

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;int mp[12][12],link[12][12],used[12],flag[12],n,m,per[12];int cnt = 0;bool dfs(int pre){     for(int i=1;i<=n;i++)         if(!used[i]&&link[pre][i])         {            used[i] = 1;            if(!flag[i]||dfs(flag[i]))            {               flag[i] = pre;               return true;            }         }      return false;}int match(){    int ans = 0;    memset(flag,0,sizeof(flag));    for(int i=1;i<=n;i++)    {       memset(used,0,sizeof(used));       ans+=dfs(i);    }    return ans;}void dfs2(int pre,int cnt1){      if(cnt==n)return ;      if(pre==n+1)      {          per[pre] = 1;          memset(link,0,sizeof(link));          for(int i=1;i<=n;i++)             for(int j=1;j<=n;j++)              if(!mp[per[j]][i]&&!mp[per[j+1]][i])link[i][j] = 1;          cnt = max(cnt,match());          return;      }      for(int i=1;i<=n;i++)          if(!(cnt1&(1<<(i-1))))          {              per[pre] = i;              dfs2(pre+1,cnt1|(1<<(i-1)));          }}int main(){    while(scanf("%d%d",&n,&m)!=EOF)    {        cnt = 0;        memset(mp,0,sizeof(mp));        while(m--)        {            int a,b;            scanf("%d%d",&a,&b);            mp[b][a] = true;        }        per[1] = 1;        dfs2(2,1);        printf("%d\n",n-cnt);    }    return 0;}
0 0
原创粉丝点击