[hdu2119]二分图最小覆盖,最大匹配

题意:给一个01矩阵,每次可以选一行或一列,打掉上面所有的1,求打掉所有的1所需的最小次数。

思路:经典的模型了,二分图最小覆盖=最大匹配。所谓最小覆盖是指选最少的点关联所有的边。容易得到将行和列看成点,1看成边,那么就是选尽量少的行和列来关联所有的1,最小覆盖模型,用最大匹配做。可以选择匈牙利算法,或者直接最大流。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

/* ******************************************************************************** */

#include <iostream>                                                                 //

#include <cstdio>                                                                   //

#include <cmath>                                                                    //

#include <cstdlib>                                                                  //

#include <cstring>                                                                  //

#include <vector>                                                                   //

#include <ctime>                                                                    //

#include <deque>                                                                    //

#include <queue>                                                                    //

#include <algorithm>                                                                //

#include <map>                                                                      //

#include <cmath>                                                                    //

using namespace std;                                                                //

                                                                                    //

#define pb push_back                                                                //

#define mp make_pair                                                                //

#define X first                                                                     //

#define Y second                                                                    //

#define all(a) (a).begin(), (a).end()                                               //

#define fillchar(a, x) memset(a, x, sizeof(a))                                      //

                                                                                    //

typedef pair<intint> pii;                                                         //

typedef long long ll;                                                               //

typedef unsigned long long ull;                                                     //

                                                                                    //

#ifndef ONLINE_JUDGE                                                                //

void RI(vector<int>&a,int n){a.resize(n);for(int i=0;i<n;i++)scanf("%d",&a[i]);}    //

void RI(){}void RI(int&X){scanf("%d",&X);}template<typename...R>                    //

void RI(int&f,R&...r){RI(f);RI(r...);}void RI(int*p,int*q){int d=p<q?1:-1;          //

while(p!=q){scanf("%d",p);p+=d;}}void print(){cout<<endl;}template<typename T>      //

void print(const T t){cout<<t<<endl;}template<typename F,typename...R>              //

void print(const F f,const R...r){cout<<f<<", ";print(r...);}template<typename T>   //

void print(T*p, T*q){int d=p<q?1:-1;while(p!=q){cout<<*p<<", ";p+=d;}cout<<endl;}   //

#endif // ONLINE_JUDGE                                                              //

template<typename T>bool umax(T&a, const T&b){return b<=a?false:(a=b,true);}        //

template<typename T>bool umin(T&a, const T&b){return b>=a?false:(a=b,true);}        //

template<typename T>                                                                //

void V2A(T a[],const vector<T>&b){for(int i=0;i<b.size();i++)a[i]=b[i];}            //

template<typename T>                                                                //

void A2V(vector<T>&a,const T b[]){for(int i=0;i<a.size();i++)a[i]=b[i];}            //

                                                                                    //

const double PI = acos(-1.0);                                                       //

const int INF = 1e9 + 7;                                                            //

                                                                                    //

/* -------------------------------------------------------------------------------- */

struct Edmonds {

    const static int maxn = 1e2 + 7;

    int n, m;

    bool g[maxn][maxn];

    bool vis[maxn];

    int left[maxn];

    void init(int n, int m) {

        this->n = n;

        this->m = m;

        memset(g, 0, sizeof(g));

        memset(left, -1, sizeof(left));

    }

    void add(int u, int v) {

        g[u][v] = true;

    }

    bool match(int u) {

        for(int v = 1; v <= m; v++)if(g[u][v] && !vis[v]) {

                vis[v] = true;

                if(left[v] == -1 || match(left[v])) {

                    left[v] = u;

                    return true;

                }

            }

        return false;

    }

    int solve() {

        int ans = 0;

        for(int i = 1; i <= n; i++) {

            memset(vis, 0, sizeof(vis));

            if(match(i)) ans++;

        }

        return ans;

    }

};/** 点从1开始编号 **/

Edmonds solver;

int main() {

#ifndef ONLINE_JUDGE

    freopen("in.txt""r", stdin);

#endif // ONLINE_JUDGE

    int n, m;

    while (cin >> n, n) {

        cin >> m;

        solver.init(n, m);

        for (int i = 0; i < n; i ++) {

            for (int j = 0; j < m; j ++) {

                int x;

                scanf("%d", &x);

                if (x) solver.add(i + 1, j + 1);

            }

        }

        cout << solver.solve() << endl;

    }

    return 0;

}

/* ******************************************************************************** */

时间: 2024-10-04 00:08:04

[hdu2119]二分图最小覆盖,最大匹配的相关文章

POJ #3041 Asteroids 3041 二分图最小覆盖 最大匹配 匈牙利算法

Description Bessie wants to navigate her spaceship through a dangerous asteroid field in the shape of an N x N grid (1 <= N <= 500). The grid contains K asteroids (1 <= K <= 10,000), which are conveniently located at the lattice points of the

二分图最大匹配==二分图最小覆盖

Problem CSAM I AMInput: Standard Input Output: Standard Output The world is in great danger!! Mental's forces have returned to Earth to eradicate humankind. Our last hope to stop this great evil is Sam “Serious” Stone. Equipped with various powerful

二分图匹配 最大匹配数+最大点覆盖 POJ 1469+POJ 3041

最大匹配数就等于最大点覆盖,因为在图里面,凡是要覆盖的点必定是连通的,而最大匹配之后,若还有点没有覆盖到,则必定有新的匹配,与最大匹配数矛盾,如果去掉一些匹配,则必定有点没有覆盖到. POJ 1469 比较简单,用的经典的二分图匹配算法. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46

二分图最小覆盖

hdu1150 最小顶点覆盖 hdu1498 50 years, 50 colors 最小顶点覆盖 +枚举 1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queu

hdu3729 I&#39;m Telling the Truth (二分图的最大匹配)

http://acm.hdu.edu.cn/showproblem.php?pid=3729 I'm Telling the Truth Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1427    Accepted Submission(s): 719 Problem Description After this year’s col

(转)二分图的最大匹配、完美匹配和匈牙利算法

转载自http://www.renfei.org/blog/bipartite-matching.html 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这就是

二分图的最大匹配、完美匹配和匈牙利算法(转)

转载自:http://blog.csdn.net/pi9nc/article/details/11848327 二分图的最大匹配.完美匹配和匈牙利算法 这篇文章讲无权二分图(unweighted bipartite graph)的最大匹配(maximum matching)和完美匹配(perfect matching),以及用于求解匹配的匈牙利算法(Hungarian Algorithm):不讲带权二分图的最佳匹配. 二分图:简单来说,如果图中点可以被分为两组,并且使得所有边都跨越组的边界,则这

二分图与网络流 带权二分图的最大匹配

二分图与网络流  带权二分图的最大匹配 在某书上偶然发现,二分图和网络流是有联系的,在子图u中建立超级源点,在子图v中建立超级汇点,源点到u和汇点到v的每条边容量设为1,u和v中的边的容量也设为1,求出最大流也就是原二分图的最大匹配了. 而求带权二分图的最大匹配也就很容易了,将u和v的权值设为容量,仍然建立超级源点和超级汇点转为网络流解决即可. 真是一切皆可网络流啊...

hdu 2063 过山车(二分图匹配最大匹配数模板)

过山车 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 10776    Accepted Submission(s): 4748 Problem Description RPG girls今天和大家一起去游乐场玩,终于可以坐上梦寐以求的过山车了.可是,过山车的每一排只有两个座位,而且还有条不成文的规矩,就是每个女生必须找个个男生做par