二分图匹配
来源:互联网 发布:ei数据库怎么进入 编辑:程序博客网 时间:2024/06/05 11:12
HDU 2063
求一个二分图的最大匹配。
完全的裸题。贴代码。
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<iostream>using namespace std;vector<int> G[1005];bool check[1005];int mac[1005];int n;void add_edge(int from,int to){ G[from].push_back(to); G[to].push_back(from);}bool dfs(int u){ for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!check[v]) { check[v]=1; if(mac[v]==-1||dfs(mac[v])) { mac[u]=v; mac[v]=u; return 1; } } } return 0;}int xyl(){ int ans=0; memset(mac,-1,sizeof(mac)); for(int i=1;i<=n;i++) { if(mac[i]==-1) { memset(check,0,sizeof(check)); if(dfs(i)) { ans++; } } } return ans;}int main(){ int k,n1,m1; while(scanf("%d",&k)!=EOF) { if(k==0) return 0; scanf("%d%d",&n1,&m1); n=n1+m1; for(int i=1;i<=n;i++) G[i].clear(); while(k--) { int A,B; scanf("%d%d",&A,&B); add_edge(A,B+n1); } printf("%d\n",xyl()); }}
HDU 2444
判断该图是否为二分图,如果是二分图就求该图的最大匹配。
判断是否为二分图是我用了一个DFS 也不知道还有没有更简单的方法。
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<stack>#include<math.h>#include<iostream>using namespace std;vector<int> G[205];bool check[205];int mac[205];int re[205];void add_edge(int from,int to){ G[from].push_back(to); G[to].push_back(from);}bool rdfs(int u,int k){ re[u]=k; bool flag=true; int k1; if(k==1) k1=2; else k1=1; for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(re[v]==k) { flag=false; break; } else if(re[v]==0) { flag=rdfs(v,k1); if(!flag) break; } } return flag;}bool dfs(int u){ for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if(!check[v]) { check[v]=true; if(mac[v]==-1||dfs(mac[v])) { mac[u]=v; mac[v]=u; return true; } } } return false;}int n;int xyl(){ int ans=0; memset(mac,-1,sizeof(mac)); for(int i=1;i<=n;i++) { if(mac[i]==-1) { memset(check,0,sizeof(check)); check[i]=1; if(dfs(i)) ans++; } } return ans;}int main(){ int m; while(scanf("%d%d",&n,&m)!=EOF) { for(int i=1;i<=n;i++) G[i].clear(); while(m--) { int A,B; scanf("%d%d",&A,&B); add_edge(A,B); } memset(re,0,sizeof(re)); bool flag=0; for(int i=1;i<=n;i++) { if(re[i]==0) { if(!rdfs(i,1)) { flag=1; break; } } } if(flag==1) printf("No\n"); else { printf("%d\n",xyl()); } }}
HDU 1281
题意:一个棋盘上有一些地方能放“车” 求最多能放多少个,又有多少个点是关键点,关键点——删除这个点能放的“车”会变少。
把行归位X集合 列归为Y集合。每个点就是从X-Y的一条边。
进行二分图匹配。然后枚举边,求出删除这条边之后的最大匹配,如果比之前的少了 就是关键点。
#include<stdio.h>#include<string.h>#include<algorithm>#include<vector>#include<iostream>using namespace std;int mac[205];bool check[205];vector<int> G[205];int z,y;int n;int k[10005][2];void add_edge(int from,int to){ G[from].push_back(to); G[to].push_back(from);}bool dfs(int u){ for(int i=0;i<G[u].size();i++) { int v=G[u][i]; if((u==z&&v==y)||(u==y&&v==z)) continue; if(!check[v]) { check[v]=1; if(mac[v]==-1||dfs(mac[v])) { mac[u]=v; mac[v]=u; return true; } } } return false;}int xyl(){ memset(mac,-1,sizeof(mac)); int ans=0; for(int i=1;i<=n;i++) { if(mac[i]==-1) { memset(check,0,sizeof(check)); if(dfs(i)) ans++; } } return ans;}int main(){ int N,M,K; int Case=0; while(scanf("%d%d%d",&N,&M,&K)!=EOF) { for(int i=1;i<=N+M;i++) G[i].clear(); int r=0; n=N+M; while(K--) { int A,B; scanf("%d%d",&A,&B); k[r][0]=A; k[r][1]=B+N; r++; add_edge(A,B+N); } z=0;y=0; int ans=xyl(); //printf("%d\n",ans); int sum=0; for(int i=0;i<r;i++) { z=k[i][0]; y=k[i][1]; int ans1=xyl(); if(ans1!=ans) { sum++; } } printf("Board %d have %d important blanks for %d chessmen.\n",++Case,sum,ans); }}
0 0
- 二分图图匹配
- 二分图匹配
- 二分图匹配
- 二分图匹配
- 二分图匹配
- 正则二分图匹配
- 二分图匹配
- 二分图匹配总结
- 二分图最大匹配
- 二分图最大匹配 。
- hdu2119二分图匹配
- 二分图匹配
- 二分图匹配
- 二分图匹配算法
- poj3020-二分图匹配
- 二分图匹配
- 二分图最大匹配
- 二分图最大匹配
- cocos2d-x入门(5)-添加背景音乐和攻击音效
- Sublime Text 中的SublimeREPL的绑定快捷键配置
- Ubuntu常用命令
- UVA 10951 Polynomial GCD 多项式欧几里德求最大公共多项式
- leetcode-3Sum
- 二分图匹配
- android 自己创建一个注释模板
- double_linked_list in Python
- nefu 636
- cocos2dx CCControlSlider
- 近期硬件的了解情况
- 潘悟云教授“新世纪语言学的转型“讲座笔记
- win7下IIS的安装和配置 图文教程
- poj/zoj Polynomial Showdown