邻接矩阵:
#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; }