uva 11138 - Nuts and Bolts(二分匹配)

Problem J

Nuts 'n' Bolts

One afternoon your cell phone rings; it's your cousin Jimmy.
"Hi Cuz," he says, "I need your help and I need it fast. I'm in the middle of a programming contest and however hard I try, I can't get one problem to finish within the two second time limit."
"Hmm... well..., isn't that a bit illegal?", you try to say to him. But he rattles on.
"I just snook out of the contest room and managed to send you my code and the sample I/O by email", he continues without pausing. "I will check my mail again in an hour, so please make it work for me."
"What about the problem description?", you ask.
"Can't do", he says, "Zoroman the Head Judge is already on my tail, so I got to go. Bye, ... and, eh, thanks."

Are you going to help him?

Jimmy's Code

#include <stdio.h>

#define MAX_BOLTS 500
#define MAX_NUTS 500

/* global copy of the input data */
int nuts,bolts;
int fits[MAX_BOLTS][MAX_NUTS];

void read_input_data(void){
int n,b;

scanf("%d%d",&bolts,&nuts);
for(b=0;b<bolts;b++){
for(n=0;n<nuts;n++){
scanf("%d",&fits[b][n]);
}
}
}

/* data used to match nuts with bolts */
int nut_used[MAX_NUTS];
int bestmatched;

void init_match(void){
int n;

bestmatched=0;
for(n=0;n<nuts;n++) nut_used[n]=0;
}

void match_bolt(int boltno, int matched){
int n;

if(boltno==bolts){
if(matched>bestmatched) bestmatched=matched;
return;
}

/* don't match this bolt */
match_bolt(boltno+1,matched);

/* match with all unused nuts that fit this bolt */
for(n=0;n<nuts;n++) if(!nut_used[n] && fits[boltno][n]){
nut_used[n]=1;
match_bolt(boltno+1,matched+1);
nut_used[n]=0;
}
}

int main(){
int cases,caseno;

scanf("%d",&cases);
for(caseno=1;caseno<=cases;caseno++){
read_input_data();
init_match();
match_bolt(0,0);
printf("Case %d: ",caseno);
printf("a maximum of %d nuts and bolts ",bestmatched);
printf("can be fitted together\n");
}

return 0;
}

This is the code that Jimmy sent you by email.
A plain-text version can be found here.

Sample Input

2
3 4
0 0 1 0
1 1 0 1
0 0 1 0
5 5
1 0 0 1 1
1 1 0 0 0
1 0 0 0 0
0 1 1 0 0
0 0 0 0 1 

Sample Output

Case 1: a maximum of 2 nuts and bolts can be fitted together
Case 2: a maximum of 5 nuts and bolts can be fitted together
 
本题题意:
行代表botle,列代表nut,每个botle只能放一个nut,1代表可放,0代表不可放,问最大匹配数?
 
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;

const int maxn = 510;
vector<int> mp[maxn];
int father[maxn] , vis[maxn] , v , B , N , ans;

void initial(){
    for(int i = 0; i < maxn; i++){
        father[i] = -1;
        vis[i] = 0;
        mp[i].clear();
    }
    v = 1;
    ans = 0;
}

void readcase(){
    scanf("%d%d" , &B , &N);
    for(int i = 0; i < B; i++){
        for(int j = 0; j < N; j++){
            int flag;
            scanf("%d" , &flag);
            if(flag) mp[i].push_back(j);
        }
    }
}

bool Hungry(int f){
    for(int k = 0; k < mp[f].size(); k++){
    	int son = mp[f][k];
		if(vis[son] != v){
			vis[son] = v;
			if(father[son] == -1 || Hungry(father[son])){
				father[son] = f;
				return true;
			}
		}
    }
    return false;
}

void computing(){
    for(int i = 0; i < B; i++){
        if(Hungry(i)) ans++;
        v++;
    }
    printf("a maximum of %d nuts and bolts can be fitted together\n" , ans);
}

int main(){
    int t;
    scanf("%d" , &t);
    for(int i = 1; i <= t; i++){
        initial();
        readcase();
        printf("Case %d: " , i);
        computing();
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值