标签:图论之二分匹配
月老准备给n个女孩与n个男孩牵红线,成就一对对美好的姻缘。
现在,由于一些原因,部分男孩与女孩可能结成幸福的一家,部分可能不会结成幸福的家庭。
现在已知哪些男孩与哪些女孩如果结婚的话,可以结成幸福的家庭,月老准备促成尽可能多的幸福家庭,请你帮他找出最多可能促成的幸福家庭数量吧。
假设男孩们分别编号为1~n,女孩们也分别编号为1~n。
1 3 4 1 1 1 3 2 2 3 2
2
这道题, 用邻接矩阵TL, 得用邻接表
代码(链式前向星):
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define M 20005
using namespace std;
struct node{
int to, next;
}s[M];
int head[M], res[555], n;
bool vis[555];
int find(int u){
int i;
for(i = head[u]; i != -1; i = s[i].next){
int temp = s[i].to;
if(!vis[temp]){
vis[temp] = 1;
if(res[temp]== 0||find(res[temp])){
res[temp] = u;
return true;
}
}
}
return false;
}
int main(){
//freopen("stdin.txt", "r", stdin);
int t, k;
scanf("%d", &t);
while(t --){
scanf("%d%d", &n, &k);
memset(res, 0, sizeof(res));
memset(head, -1, sizeof(head));
int a, b;
for(int i = 0; i < k; i ++){
scanf("%d%d", &a,&b);
s[i].to = b;
s[i].next = head[a];
head[a] = i;
}
int ans = 0;
for(int i = 1; i <= n; i ++){
memset(vis, 0, sizeof(vis));
if(find(i)) ++ans;
}
printf("%d\n", ans);
}
}
#include <stdio.h>
#include <string.h>
#include <vector>
#define M 555
using namespace std;
vector <int > map[M];
int vis[M], res[M];
int n;
int find(int a){
int i;
for(i = 0; i < map[a].size(); i ++){
if(!vis[map[a][i]]){
vis[map[a][i]] = 1;
if(res[map[a][i]] == 0||find(res[map[a][i]])){
res[map[a][i]] = a;
return 1;
}
}
}
return 0;
}
int main(){
int t, k;
scanf("%d", &t);
while(t --){
scanf("%d%d", &n, &k);
int i;
memset(map, 0, sizeof(map));
memset(res, 0, sizeof(res));
int a, b, ans = 0;
for(i = 0; i < k; i ++){
scanf("%d%d", &a, &b);
map[a].push_back(b);
}
for(i = 1; i <= n; i ++){
memset(vis, 0,sizeof(vis));
if(find(i)) ++ans;
}
printf("%d\n", ans);
}
return 0;
} 标签:图论之二分匹配
原文地址:http://blog.csdn.net/shengweisong/article/details/40677239