二分图行列匹配---> hdu2119,hdu1498

hdu2119

题意:给定一个矩形方格,每个格子里面的数字是0或者1,每次操作可以把一整行或列的1变成0,问最少多少次操作能将1全部变为0

一次可以消除某一行或者某一列的1
但是可以这么想,最多有多少个1即不在同一行,也不在同一列,有多少个,那么就要消多少次
那么就是求行和列的最大匹配

 1 #include <stdio.h>
 2 #include <string.h>
 3 const int N = 100 + 10;
 4 int Map[N][N];
 5 bool vis[N];
 6 int cy[N];
 7 int n,m;
 8 bool dfs(int u)
 9 {
10     for(int i=0; i<m; ++i)
11     {
12         if(!vis[i] && Map[u][i])
13         {
14             vis[i] = true;
15             if(cy[i] == -1 || dfs(cy[i]))
16             {
17                 cy[i] = u;
18                 return true;
19             }
20         }
21     }
22     return false;
23 }
24 int MaxMatch()
25 {
26     memset(cy, -1, sizeof(cy));
27     int ans = 0;
28     for(int i=0; i<n; ++i)
29     {
30         memset(vis, 0, sizeof(vis));
31         ans += dfs(i);
32     }
33     return ans;
34 }
35 int main()
36 {
37     int i,j;
38     while(true)
39     {
40         scanf("%d",&n);
41         if(n == 0)
42             break;
43         scanf("%d",&m);
44         for(i=0; i<n; ++i)
45             for(j=0; j<m; ++j)
46             {
47                 scanf("%d",&Map[i][j]);
48             }
49         int ans = MaxMatch();
50         printf("%d
",ans);
51     }
52 }

 hdu1498

比上面那题复杂一点,不过也是一样,每次只能消一行或者一列相同颜色的气球

一共就50中颜色,我们可以枚举每一种颜色构成的矩形,然后对其进行行列匹配,如果最大匹配 > k , 那么就不能在k次内完全消除该种颜色的气球

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <vector>
 4 using namespace std;
 5 const int N = 100 + 10;
 6 const int M = 50 + 10;
 7 int Map[M][N][N];
 8 int color[M];
 9 bool vis[N];
10 int cy[N];
11 int ans[M];
12 vector<int> G[N];
13 int cnt;
14 int n,k;
15 void init()
16 {
17     for(int i=0; i<n; ++i)
18         G[i].clear();
19     
20 }
21 bool dfs(int u)
22 {
23     for(int i=0; i<G[u].size(); ++i)
24     {
25         int v = G[u][i];
26         if(!vis[v])
27         {
28             vis[v] = true;
29             if(cy[v] == -1||dfs(cy[v]))
30             {
31                 cy[v] = u;
32                 return true;
33             }
34         }
35     }
36     return false;
37 }
38 int MaxMatch()
39 {
40     memset(cy, -1, sizeof(cy));
41     int cnt = 0;
42     for(int i=0; i<n; ++i)
43     {
44         memset(vis, 0, sizeof(vis));
45         cnt += dfs(i);
46     }
47     return cnt;
48 }
49 int main()
50 {
51     //freopen("in.txt","r",stdin);
52     int i,j;
53     while(true)
54     {
55         scanf("%d%d",&n,&k);
56         if(n == 0 && k==0)
57             break;
58         int t;
59         memset(Map, 0, sizeof(Map));
60         memset(color, 0, sizeof(color));
61         cnt = 0;
62         for(i=0; i<n; ++i)
63             for(j=0; j<n; ++j)
64             {
65                 scanf("%d",&t);
66                 Map[t][i][j] = 1;
67                 color[t] = 1;
68             }
69         for(t=1; t<=50; ++t)
70             if(color[t])//枚举每一种颜色构成的矩阵
71             {
72                 init();    
73                 for(i=0; i<n; ++i)
74                     for(j=0; j<n; ++j)
75                     {
76                         if(Map[t][i][j] == 1)
77                             G[i].push_back(j);//用vector存储
78                     }
79                 int tmp = MaxMatch();
80                 if(tmp > k)
81                     ans[cnt++] = t;
82             }
83         if(cnt == 0)
84             puts("-1");
85         else
86         {
87             printf("%d",ans[0]);
88             for(i=1; i<cnt; ++i)
89                 printf(" %d",ans[i]);
90             puts("");
91         }
92     }
93     return 0;    
94 }
原文地址:https://www.cnblogs.com/justPassBy/p/4020885.html