Necklace HDU

来源:互联网 发布:ubuntu中文五笔输入法 编辑:程序博客网 时间:2024/05/21 10:17

题意: 给出n个yang珠子n个yin珠子。

给出抵消的编号

询问排成环,最少可以形成个被抵消的yang珠子

思路:

枚举yang珠子在yin珠子排列的可能。一次求出不抵消的匹配 数,那么抵消的=n-不抵消的


#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <iostream>using namespace std;const int maxn=105;int mp[maxn][maxn];//mp数组存的是阴阳珠是否抵消int a[maxn];//用来存储排列的方式int vec[maxn][maxn];int pre[maxn];int vis[maxn];int n;bool dfs(int u){    for(int v=1; v<=n; v++)    {        if(vec[u][v]&&!vis[v])        {            vis[v]=true;            if(pre[v]==-1||dfs(pre[v]))            {                pre[v]=u;                return true;            }        }    }    return false;}int hungary(){    int res=0;    memset(pre,-1,sizeof(pre));    for(int u=1; u<=n; u++)    {        memset(vis,0,sizeof(vis));        if(dfs(u))            res++;    }    return res;}int main(){    int m;    while(~scanf("%d%d",&n,&m))    {        if(n==0)        {            printf("0\n");            continue;        }        memset(mp,0,sizeof(mp));        for(int i=1; i<=m; i++)        {            int a,b;            scanf("%d%d",&a,&b);            mp[a][b]=1;        }        ///mp 表示 a号阳珠子 与b号阴珠子 抵消        int ans=0x3f3f3f3f;        for(int i=1; i<=n; i++)            a[i]=i;        ///初始化,之后枚举阳珠插到阴珠子的情况        do        {            memset(vec,0,sizeof(vec));            for(int i=1; i<=n; i++) ///i 阳,j 阴            {                for(int j=1; j<=n; j++)                {                    int l=a[j],r=a[j+1];                    if(j==n)                        r=a[1];                    if(!mp[i][l]&&!mp[i][r])                    {                        vec[i][j]=1;                    }                }            }            int num=hungary();            ///最大匹配到的未抵消的数量 =n -  抵消掉的            ans=min(ans,n-num);        }        while(next_permutation(a+2,a+n+1));        printf("%d\n",ans);    }    return 0;}