二分图的两种算法-最大匹配与最优匹配 poj--1469,2536

来源:互联网 发布:明星自己开淘宝店铺 编辑:程序博客网 时间:2024/06/13 06:31

1.最大匹配
题目大意:给你p门课程和n个学生,一个学生可以选0门,1门,或者多门课 程,现在要求一个由p个学生组成的集合,满足下列2个条件:
(1).每个学生选择一个不同的课程
(2).每个课程都有不同的代表
如果满足,就输出YES

#include<cstdio>#include<cstring>using namespace std;#define P 110#define N 310int map[P][N];int match[N];bool use[N];int p, n;bool find(int u) //u是课程{    for(int i = 1; i <= n; ++i)    {        if(!use[i] && map[u][i]) //标记匹配的学生        {            use[i] = true;            if(match[i] == - 1 || find(match[i]))            {                match[i] = u;                return true;            }        }    }    return false;}int sum(){    int sumall = 0;    for(int i = 1; i <= p; ++i) //统计匹配的课程    {        memset(use, false, sizeof(use));        if(find(i))            sumall++;    }    return sumall;}int main(){    int ncase;    int stunum, temp, ans;    scanf("%d", &ncase);    while(ncase--)    {        memset(map, 0, sizeof(map));        memset(match, -1, sizeof(match));        scanf("%d%d", &p, &n);        for(int i = 1; i <= p; ++i)        {            scanf("%d", &stunum);            for(int j = 1; j <= stunum; ++j)            {                scanf("%d", &temp);                map[i][temp] = 1; //temp号学生喜欢i号课程            }        }        ans = sum();        printf("%s\n", ans == p ? "YES" : "NO");    }    return 0;}

2.最优匹配
题目大意:一块田地上有n只gopher和m个gopher洞,并且知道gopher的奔跑速度v。如果gopher的天敌出现,gopher不能在t时间内跑入一个洞内,就会有危险。每个洞只能住一只gopher,给出每个洞的坐标和每只gopher的坐标,问你天敌出现的时候,最少有几只gopher会有危险。

#include <stdio.h>#include <string.h>const int N = 105;int n, m, s, v, link[N], vis[N], g[N][N];double x1[N], y1[N], x2[N], y2[N], x;bool dfs(int u){    for (int i = 0; i < m; i++)        if (!vis[i] && g[u][i])        {            vis[i] = 1;            if (link[i] == -1 || dfs(link[i]))            {                link[i] = u;                return true;            }        }    return false;}int hungary(){    int res = 0;    memset(link, -1, sizeof(link));    for (int i = 0; i < n; i++)    {        memset(vis, 0, sizeof(vis));        if (dfs(i))            res++;    }    return res;}bool judge(int i, int j){    if ((x1[i] - x2[j]) * (x1[i] - x2[j]) + (y1[i] - y2[j]) * (y1[i] - y2[j]) > x)        return false;    return true;}int main(){    while (~scanf("%d%d%d%d", &n, &m, &s, &v))    {        memset(g, 0, sizeof(g));        x = s * v * s * v * 1.0;        for (int i = 0; i < n; i++)            scanf("%lf%lf", &x1[i], &y1[i]);        for (int i = 0; i < m; i++)            scanf("%lf%lf", &x2[i], &y2[i]);        for (int i = 0; i < n; i++)            for (int j = 0; j < m; j++)                if (judge(i, j))                    g[i][j] = 1;        printf("%d\n", n - hungary());    }    return 0;}
0 0