HNU 10111 0-1矩阵

http://acm.hnu.cn/online/?action=problem&type=show&id=10111

题意:中文

题解:在龙哥的帮助下正了二分图匹配的三观……以前的理解繁琐,或者有点儿错吧……二分图匹配从左往右匹配,找增广路。顶点数和match()不需要那么麻烦。

  1 //
  2 //  main.cpp
  3 //  POJ 3041
  4 //
  5 //  Created by zhang on 14-4-16.
  6 //  Copyright (c) 2014年 apple. All rights reserved.
  7 //
  8 
  9 #include <iostream>
 10 #include <cstring>
 11 #include <cstdio>
 12 #include <cstdlib>
 13 #include <cmath>
 14 #include <string>
 15 #include <vector>
 16 #include <list>
 17 #include <map>
 18 #include <queue>
 19 #include <stack>
 20 #include <bitset>
 21 #include <algorithm>
 22 #include <numeric>
 23 #include <functional>
 24 #include <set>
 25 #include <fstream>
 26 
 27 using namespace std;
 28 
 29 const int maxn=10010;
 30 int g1[maxn];
 31 int g2[maxn];
 32 int V=0;
 33 vector<int> G[maxn*2 ];
 34 int match[maxn];
 35 bool used[maxn];
 36 int g[maxn][maxn];
 37 
 38 void add_edge(int u,int v){
 39     G[u].push_back(v);
 40     G[v].push_back(u);
 41 }
 42 
 43 bool dfs(int v)
 44 {
 45     used[v]=true;
 46     for (int i=0; i<G[v].size(); i++) {
 47         int u=G[v][i];
 48         int w=match[u];
 49         if(used[w]) continue;
 50         if (w<0||dfs(w)) {
 51            // match[v]=u;
 52             match[u]=v;
 53             return true;
 54         }
 55     }
 56     return false;
 57 }
 58 
 59 int b_match()
 60 {
 61     int res=0;
 62     memset(match, -1, sizeof(match));
 63     for (int v=0; v<V; v++) {
 64         if (match[v]<0) {
 65             memset(used, 0, sizeof(used));
 66             if (dfs(v)) {
 67                 res++;
 68             }
 69         }
 70     }
 71     return res;
 72 }
 73 int main()
 74 {
 75     //freopen("/Users/apple/Desktop/HNU 10111/HNU 10111/in", "r", stdin);
 76     //freopen("/Users/apple/Desktop/HNU 10111/HNU 10111/out", "w", stdout);
 77     int N,M;
 78     char s[110][110];
 79     while((scanf("%d",&N))!=EOF&&N!=0){
 80         scanf("%d",&M);
 81         V=N;
 82         //cout<<V<<endl;
 83         int K=0;
 84         int p=0;
 85         int q=0;
 86         getchar();
 87         for (int i=0; i<N; i++) {
 88             for (int j=0; j<M; j++) {
 89                 s[i][j]=getchar();
 90               //  cout<<s[i][j];
 91                 if (s[i][j]=='1') {
 92                     K++;
 93                     g1[p]=i;
 94                     g2[q]=j;
 95                     //cout<<"g1 g2 "<<i <<" "<<j<<" "<<g1[p]<<" "<<g2[q]<<endl;
 96                     p++;
 97                     q++;
 98                 }
 99             }
100             getchar();
101            // puts("");
102         }
103         //cout<<"K "<<K<<endl;
104         for (int i=0; i<K; i++) {
105             //cout<<g1[i]<<g2[i]<<endl;
106             add_edge(g1[i],N +g2[i]);
107          }
108         printf("%d\n",b_match());
109         for (int i=0; i<K*2; i++) {
110             G[i].clear();
111         }
112     }
113     
114     return 0;
115 }

 

转载于:https://www.cnblogs.com/der-z/p/3697485.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值