邻接矩阵:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
using namespace std;
int mp[2100][2100]; // 图的存储矩阵
int n, m;
int ans;
bool vis[2100]; // 当前搜索过程中是否被访问过
int link[2100]; // y集合中的点在x集合中的匹配点 -1表示未匹配
bool find_(int x) {
for (int i=1; i<=n; ++i) {
if (mp[x][i] && !vis[i]) { // 有边相连
vis[i] = 1; // 标记该点
if (link[i] == -1 || find_(link[i])) { //该点未匹配 或者匹配的点能找到增光路
link[i] = x; // 删掉偶数条边 加进奇数条边
return true; // 找到增光路
}
}
}
return false;
}
void match() {
//初始化
ans = 0;
memset(link, -1, sizeof(link));
for (int i=1; i<=n; ++i) {
memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
if (find_(i)) // 如果能搜索到 匹配数加1
ans++;
}
return;
}
int main() {
while(cin >> n >> m) {
memset(mp, 0, sizeof(mp));
for (int i=0; i<m; ++i) {
int x, y;
cin >> x >> y;
mp[x][y] = 1;
mp[y][x] = 1;
}
//判断是不是二分图 过
match();
cout << ans/2 << endl;
}
return 0;
}
邻接表:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <queue>
#define maxn 205
using namespace std;
int n, m;
int ans;
bool vis[maxn]; // 当前搜索过程中是否被访问过
int link[maxn]; // y集合中的点在x集合中的匹配点 -1表示未匹配
int head[maxn];
int tot;
struct Node {
int v, nxt;
}edge[maxn*maxn];
void addEdge(int u, int v) {
edge[tot].v = v;
edge[tot].nxt = head[u];
head[u] = tot++;
}
bool find_(int x) {
for (int i=head[x]; i!=-1; i=edge[i].nxt) { // 遍历以x为顶点的所有边
int v = edge[i].v;
if (vis[v]) continue; // 如果v在当前寻找增光路过程中被访问过
vis[v] = 1; // 标记访问
if (link[v] == -1 || find_(link[v])) { // 如果v点没有被匹配过 或者 匹配点能找到增光路
link[v] = x; // 增广路奇偶倒置
return true;
}
}
return false;
}
void match() {
ans = 0;
memset(link, -1, sizeof(link));
for (int i=1; i<=n; ++i) {
memset(vis, 0, sizeof(vis)); // 从集合的每个点依次搜索
if (find_(i)) // 如果能搜索到 匹配数加1
ans++;
}
return;
}
int main() {
while(cin >> n >> m) {
tot = 0;
memset(head, -1, sizeof(head));
for (int i=0; i<m; ++i) {
int x, y;
cin >> x >> y;
addEdge(x, y);
addEdge(y, x);
}
match();
cout << ans/2 << endl;
}
return 0;
}
浙公网安备 33010602011771号