hihoCoder 1122 二分图最大匹配 最大流
来源:互联网 发布:时文朝 银联数据 编辑:程序博客网 时间:2024/05/29 10:33
题意
- 求二分图最大匹配
思路
- 没有用匈牙利算法,而是试了试要带去的两个最大流模板。。
- 就是加一个源点,一个汇点,源到二分图集合1的点加一个流量为1的边,集合1到集合2的边设置为流量1,集合2的点到汇点加入流量1的边
实现
- 模板1实现
#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <cstdio> #include <vector>using namespace std;const int MAXN = 2000;const int maxn = 2000;//最大流ISAP部分const int MAXM = 20005;const int INF = 0x3f3f3f3f;struct Edge{ int to,next,cap,flow;}edge[MAXM];int tol;int head[MAXN];int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];void init(){ tol = 0; memset(head,-1,sizeof(head));}void addedge(int u,int v,int w,int rw = 0){ edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u]; edge[tol].flow = 0; head[u] = tol++; edge[tol].to = u; edge[tol].cap = rw; edge[tol].next = head[v]; edge[tol].flow = 0; head[v] = tol++;}int sap(int start,int end,int N){ memset(gap,0,sizeof(gap)); memset(dep,0,sizeof(dep)); memcpy(cur,head,sizeof(head)); int u = start; pre[u] = -1; gap[0] = N; int ans = 0; while(dep[start] < N) { if(u == end) { int Min = INF; for(int i = pre[u]; i != -1;i = pre[edge[i^1].to]) if(Min > edge[i].cap - edge[i].flow) Min = edge[i].cap - edge[i].flow; for(int i = pre[u];i != -1;i = pre[edge[i^1].to]) { edge[i].flow += Min; edge[i^1].flow -= Min; } u = start; ans += Min; continue; } bool flag = false; int v; for(int i = cur[u];i != -1;i = edge[i].next) { v = edge[i].to; if(edge[i].cap - edge[i].flow && dep[v] + 1 == dep[u]) { flag = true; cur[u] = pre[v] = i; break; } } if(flag) { u = v; continue; } int Min = N; for(int i = head[u];i != -1;i = edge[i].next) if(edge[i].cap - edge[i].flow && dep[edge[i].to] < Min) { Min = dep[edge[i].to]; cur[u] = i; } gap[dep[u]]--; if(!gap[dep[u]])return ans; dep[u] = Min+1; gap[dep[u]]++; if(u != start)u = edge[pre[u]^1].to; } return ans;}//the end of 最大流部分int vis[maxn];vector<int> g[maxn];#define pb push_backvoid dfs(int u){ for (int e=0;e<g[u].size();e++){ int v = g[u][e]; if (vis[v] == -1){ vis[v] = (vis[u] ^ 1); dfs(v); } }}int main(){ int n,m; cin>>n>>m; int u,v; for (int i=0;i<m;i++){ scanf("%d%d",&u,&v); g[u].pb(v); g[v].pb(u); } memset(vis,-1,sizeof(vis)); for (int i=1;i<=n;i++){ if (vis[i] == -1){ vis[i] = 0; dfs(i); } } init(); for (int i=1;i<=n;i++){ if (vis[i] == 0){ addedge(0,i,1); for (int e=0;e<g[i].size();e++){ v = g[i][e]; addedge(i,v,1); } } else{ addedge(i,n+1,1); } } cout << sap(0,n+1,n+2) << "\n"; return 0;}
- 实现2
#include <iostream>#include <cstring>#include <cmath>#include <algorithm>#include <queue>#include <cstdio> #include <vector>using namespace std;const int maxn = 2000;const int inf = 0x3f3f3f3f;struct EdmondsKarp{ //用到外部变量maxn,maxm,具体使用不非得按照模板 int n,m; int g[maxn][maxn]; int flow[maxn]; int path[maxn]; queue<int> q; void init(int nn=0) { n = nn; memset(g,0,sizeof(g)); memset(flow,0,sizeof(flow)); memset(path,-1,sizeof(path)); } void addOne(int u,int v,int yuan) { g[u][v] += yuan; m += 2; } int bfs(int s,int t) { int i; memset(path,-1,sizeof(path)); flow[s] = inf; //如果不加这句话,bfs内部就要一共三个判断 path[s] = s; q.push(s); while(q.size()>0) { int tmp = q.front(); q.pop(); //这里i从0开始还是1开始,视情况而定 for(i=0;i<n;i++) { if(g[tmp][i]>0 && path[i]==-1) { flow[i] = min(g[tmp][i],flow[tmp]); path[i] = tmp; q.push(i); if(i==t) { break; } } } if(path[t] != -1) break; } while(q.size()>0) q.pop(); if(path[t] == -1) return 0; else return flow[t]; } int go(int s,int t) { int ret = 0; while(bfs(s,t)) { int now = path[t]; int pre = t; ret += flow[t]; while(pre != s) { g[now][pre] -= flow[t]; g[pre][now] += flow[t]; pre = now; now = path[now]; } } return ret; }}edk;int vis[maxn];vector<int> g[maxn];#define pb push_backvoid dfs(int u){ for (int e=0;e<g[u].size();e++){ int v = g[u][e]; if (vis[v] == -1){ vis[v] = (vis[u] ^ 1); } }}int main(){ int n,m; cin>>n>>m; int u,v; for (int i=0;i<m;i++){ scanf("%d%d",&u,&v); g[u].pb(v); g[v].pb(u); } memset(vis,-1,sizeof(vis)); for (int i=1;i<=n;i++){ if (vis[i] == -1){ vis[i] = 0; dfs(i); } } edk.init(n+2); for (int i=1;i<=n;i++){ if (vis[i] == 0){ edk.addOne(0,i,1); for (int e=0;e<g[i].size();e++){ v = g[i][e]; edk.addOne(i,v,1); } } else{ edk.addOne(i,n+1,1); } } cout << edk.go(0,n+1) << "\n"; return 0;}
0 0
- hihoCoder 1122 二分图最大匹配 最大流
- 二分图最大匹配(HihoCoder
- hihocoder 1122最大二分匹配匈牙利算法
- hihoCoder - 1122 - 二分图最大匹配之匈牙利算法
- hihoCoder 1122 二分图二•二分图最大匹配之匈牙利算法
- hihocoder 1122 : 二分图二•二分图最大匹配之匈牙利算法
- hihocoder 1122 : 二分图二•二分图最大匹配之匈牙利算法
- [HihoCoder]#1122 : 二分图二•二分图最大匹配之匈牙利算法
- hihocoder 1122 : 二分图二•二分图最大匹配之匈牙利算法
- hihocoder 1122 : 二分图二•二分图最大匹配之匈牙利算法
- hihocoder 1158 质数相关(二分图匹配 最大独立集)
- bzoj1433_最大流|二分图最大匹配
- 二分图最大匹配
- 二分图最大匹配 。
- 二分图最大匹配
- 二分图最大匹配
- 二分图最大匹配
- 二分图最大匹配
- 分析函数操作
- Java 理论与实践: 正确使用 Volatile 变量
- 2、OpenSceneGraph中添加节点、删除节点、隐藏节点以及添加开关的用法
- 【springmvc+mybatis项目实战】杰信商贸-29.购销合同技术难点分析
- 机器学习、深度神经网络的认识与结论
- hihoCoder 1122 二分图最大匹配 最大流
- OpenCV - 参考网站、牛人博客
- RelativeLayout用到的一些重要的属性
- 【springmvc+mybatis项目实战】杰信商贸-30.出口报运增删查修mapper+Dao+Service+Controller
- openjudge help Jimmy
- Apache访问日志详解
- 嵌入式经典面试题
- [Numerical_analysis]the_third_project
- 【读书笔记】统计学:从数据到结论 第十章