HDU 5727 Necklace(二分图匹配)

来源:互联网 发布:中国知网引文数据库 编辑:程序博客网 时间:2024/05/17 05:55

题目分析

根据阴珠子和阳珠子的互斥关系来建立二分图,但是大家发现如果是拿阴和阳来建立二分图很难建立,这里面我们首先对阴珠子进行全排列,然后根据阴珠子所在的位置,找到每一个位置上有哪些阳珠子能放,并且建立边,这样一个二分图就出来,很明显求出二分图的最大匹配,然后用N-二分图的最大匹配就是所求的答案,然后找到这些答案的最小值输出即可。

#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>using namespace std;const int maxn = 15;const int INF = 0x3f3f3f3f;int a[maxn], head[maxn], vis[maxn], link[maxn], maze[maxn][maxn], tot;struct Edge{    int to, next;}e[maxn*maxn];void addedge(int from,int to){    e[tot].to = to;    e[tot].next = head[from];    head[from] = tot++;}bool dfs(int u){  //匈牙利算法    for(int i = head[u]; i != -1; i = e[i].next){        int v = e[i].to;        if(!vis[v]){            vis[v] = 1;            if(link[v] == -1 || dfs(link[v])){                link[v] = u;                return true;            }        }    }    return false;}void init(){    memset(head, -1, sizeof(head));    memset(vis, 0, sizeof(vis));    memset(link, -1, sizeof(link));    tot = 0;}int main(){    int N,M;    while(scanf("%d%d", &N, &M) != EOF){        init();        int from, to;        memset(maze, 0, sizeof(maze));        while(M--){            scanf("%d %d", &from, &to);            maze[from][to] = 1;        }        if(!N){  //0的时候很明显直接跳出即可            printf("0\n");            continue;        }        for(int i = 1; i <= N; i++) a[i] = i;        int ans = INF;        do{            init();            for(int i = 1; i <= N; i++){  //i表示第i个位置                if(i == 1){                    for(int j = 1; j <= N; j++)  //找到第i个位置能放的珠子                        if(!maze[j][a[1]] && !maze[j][a[N]]) addedge(i, j);                }                else{                    for(int j = 1; j <= N; j++)                        if(!maze[j][a[i]] && !maze[j][a[i-1]]) addedge(i, j);                }            }            int cnt = 0;            for(int i = 1; i <= N; i++){                memset(vis, 0, sizeof(vis));                if(dfs(i)) cnt++;            }            ans = min(ans, N-cnt);        }while(next_permutation(a+1, a+1+N)&ans);        printf("%d\n", ans);    }    return 0;}
0 0
原创粉丝点击