HDU——5737 Necklace

来源:互联网 发布:nba2k17乔丹捏脸数据 编辑:程序博客网 时间:2024/06/06 17:49

hdu 5737 Necklace

题解

1.利用next_permulation 函数 枚举全排列下阴珠的排列;
2.利用插空法,建二分图,<阳珠——空>,被污染则<阳珠——空>为false;
3.匈牙利算法求得最大匹配数ans;
4.n-ans即为至少要被污染的阳珠数;

TLE优化:
1.全排时只要排n-1个
2.if(ans == n);即得到最大匹配了,可以直接break;

AC code

#include <bits/stdc++.h>using namespace std;const int maxn = 1e5+10;const int  INF = 0x3f3f3f3f;bool mp[12][12];int p[12];vector <int> g[12];bool vis[12];int line[12];void build(int n){   for(int i = 0; i < n; i++)       for(int j = 0; j < n; j++)            if(mp[i][p[j%n]] || mp[i][p[(j+1)%n]]);            else g[i].push_back(j%n);}bool dfs(int u){    for(int i = 0; i < g[u].size(); i++)    {        int v = g[u][i];        if(!vis[v])        {            vis[v] = true;            if(line[v] == -1 || dfs(line[v]))            {                line[v] = u;                return true;            }        }    }    return false;}int Max_match(int n){    memset(line,-1,sizeof(line));    int all = 0;    for(int i = 0; i < n; i++)    {        memset(vis,false,sizeof(vis));        if(dfs(i))  all++;    }    return all;}int main(){    int n,m;    while(~scanf("%d%d",&n,&m))    {        memset(mp,false,sizeof(mp));        for(int i = 0; i < m; i++)        {            int j,k;            scanf("%d%d",&j,&k);            mp[j-1][k-1] = true;//berwuran        }        int ans = 0;        for(int i = 0; i <= n; i++)  p[i] = i;        do{            for(int i = 0; i < n; i++)                g[i].clear();            build(n);            ans = max(ans,Max_match(n));            if(ans == n) break;        } while(next_permutation(p+1,p+n));        printf("%d\n",n-ans);    }}