二分图的匹配
来源:互联网 发布:gamemaker 源码 编辑:程序博客网 时间:2024/05/14 11:04
方法一:利用网络流新增源点和汇点的方法
#include <iostream>#include <vector>#include <climits>#include <cstring>using namespace std;const int MAX_V = 1100;struct edge{int to, cap, rev;}; ///邻接表表示,点,容量,反向边vector<edge> G[MAX_V];bool used[MAX_V];/// 贪心策略: 1.找到f < c 或者 f > 0 的边,寻找路径 2.不存在路径则结束,若存在路径则返回1继续寻找void add_edge(int from, int to, int cap) { ///添加边 G[from].push_back((edge){to, cap, G[to].size()}); G[to].push_back((edge){from, 0, G[from].size() - 1});}int dfs(int v, int t, int f) { if(v == t) return f; used[v] = true; for(int i = 0; i < G[v].size(); ++i) { edge &e = G[v][i]; if(!used[e.to] && e.cap > 0) { int d = dfs(e.to, t, min(f, e.cap)); if(d > 0) { e.cap -= d; ///该边减小容量 G[e.to][e.rev].cap += d; ///反向边增加容量 return d; } } }}int max_flow(int s, int t) { int flow = 0; for(;;) { memset(used, 0, sizeof(used)); int f = dfs(s, t, INT_MAX); if(f == 0) return flow; flow += f; }}/// 0 ~ N - 1 计算机对应的顶点/// N ~ N + K - 1 任务对应的顶点int N, K;int can[MAX_V][MAX_V];void solve() { int s = N + K, t = s + 1; ///s 为新的源点,t为新的汇点 for(int i = 0; i < N; ++i) { add_edge(s, i, 1); } for(int i = 0; i < K; ++i) { add_edge(N + i, t, 1); } for(int i = 0; i < N; ++i) { for(int j = 0; j < K; ++j) { if(can[i][j]) { add_edge(i, N + j, 1); } } } cout << max_flow(s, t) << endl;}int main(){ cin >> N >> K; int k; cin >> k; memset(can, 0, sizeof(can)); for(int i = 0; i < k; ++i) { int p, q; cin >> p >> q; can[p][q] = 1; can[q][p] = 1; } solve(); return 0;}/*3 350 00 11 01 22 1*/
方法二:贪心法进行增广路
#include <iostream>#include <vector>#include <cstring>const int MAX_V = 1100;const int INF = INT_MAX;using namespace std;int V;vector<int> G[MAX_V];int match[MAX_V];bool used[MAX_V];///贪心策略:依次遍历每个点,进行增广路径,规则为:未匹配,或已经匹配但未进行遍历的点。void add_edge(int u, int v){ G[u].push_back(v); G[v].push_back(u);}bool dfs(int v){ used[v] = true; for(int i = 0; i < G[v].size(); ++i) { int u = G[v][i], w = match[u]; if(w < 0 || !used[w] && dfs(w)) { ///该处为该贪心算法关键点 match[v] = u; match[u] = v; return true; } } return false;}int bipartite_matching(){ int res = 0; memset(match, -1, sizeof(match)); for(int v = 0; v < V; v++) { if(match[v] < 0) { memset(used, 0, sizeof(used)); if(dfs(v)) { res++; } } } return res;}int main(){ int s, x, y; cin >> s >> V; for(int i = 0; i < s; ++i) { cin >> x >> y; add_edge(x, y); } cout << bipartite_matching() << endl; return 0;}/*5 60 30 41 31 52 4*/
0 0
- 二分图的匹配
- 二分图匹配---- 二分的真谛
- 二分图的最大匹配完美匹配
- 二分图的最大匹配
- 二分图匹配的基础知识
- 二分图的最大匹配
- 二分图的最大匹配
- nefu475二分图的匹配
- 二分图的最佳匹配
- 二分图的最大匹配
- 二分图的最大匹配
- 二分图的最大匹配
- 二分图的最大匹配
- 二分图的多重匹配
- 二分图的最大匹配
- 二分图的最大匹配
- 二分匹配的建图
- 二分图的多重匹配
- ICMP报文和ping命令
- 一些JavaScript小技巧
- leetcode [Contains Duplicate]//待整理多种解法
- SRM 556 Div1 500
- java源码Integer类toBinaryString()方法探究
- 二分图的匹配
- 一篇SSM框架整合友好的文章(三)
- LeetCode075 Sort Colors
- POJ-1017 Packets
- 数组
- There is no getter for property named 'itmesCustom' in 'class com.ssm.po.Ite
- Damageable.cs
- 系统相关
- hdu3726:Graph and Queries(treap+启发式合并+离线)