首页 > 代码库 > 二分图算法模板汇总
二分图算法模板汇总
Hungary算法
.c
#include <std<pre name="code" class="cpp">#include <iostream> #include <cstring> using namespace std; //定义链表 struct link { int data; //存放数据 link* next; //指向下一个节点 link(int=0); }; link::link(int n) { data=http://www.mamicode.com/n;>
io.h>#include <string.h>int n1,n2,m,ans;int result[101]; //记录V2中的点匹配的点的编号bool state [101]; //记录V2中的每个点是否被搜索过bool data[101][101];//邻接矩阵 true代表有边相连void init() { int t1,t2; memset(data,0,sizeof(data)); memset(result,0,sizeof(result)); ans = 0; scanf("%d%d%d",&n1,&n2,&m); for (int i = 1; i <= m; i++) { scanf("%d%d",&t1,&t2); data[t1][t2] = true; } return;}bool find(int a) { for (int i = 1; i <= n2; i++) { if (data[a][i] == 1 && !state[i]) { //如果节点i与a相邻并且未被查找过 state[i] = true; //标记i为已查找过 if (result[i] == 0 //如果i未在前一个匹配M中 || find(result[i])) { //i在匹配M中,但是从与i相邻的节点出发可以有增广路 result[i] = a; //记录查找成功记录 return true; //返回查找成功 } } } return false;}int main() { init(); for (int i = 1; i <= n1; i++) { memset(state,0,sizeof(state)); //清空上次搜索时的标记 if (find(i)) ans++; //从节点i尝试扩展 } printf("%d\n",ans); return 0;}.cpp
#include<iostream> #include<cstring> using namespace std; int map[105][105]; int visit[105],flag[105]; int n,m; bool dfs(int a) { for(int i=1;i<=n;i++) { if(map[a][i] && !visit[i]) { visit[i]=1; if(flag[i]==0 || dfs(flag[i])) { flag[i]=a; return true; } } } return false; } int main() { while(cin>>n>>m) { memset(map,0,sizeof(map)); for(int i=1;i<=m;i++) { int x,y; cin>>x>>y; map[x][y]=1; } memset(flag,0,sizeof(flag)); int result=0; for(int i=1;i<=n;i++) { memset(visit,0,sizeof(visit)); if(dfs(i)) result++; } cout<<result<<endl; } return 0; }link.cpp
#include <iostream> #include <cstring> using namespace std; //定义链表 struct link { int data; //存放数据 link* next; //指向下一个节点 link(int=0); }; link::link(int n) { data=http://www.mamicode.com/n;>byvoid
#include <stdio.h> #include <string.h> #define MAX 102 long n,n1,match; long adjl[MAX][MAX]; long mat[MAX]; bool used[MAX]; FILE *fi,*fo; void readfile() { fi=fopen("flyer.in","r"); fo=fopen("flyer.out","w"); fscanf(fi,"%ld%ld",&n,&n1); long a,b; while (fscanf(fi,"%ld%ld",&a,&b)!=EOF) adjl[a][ ++adjl[a][0] ]=b; match=0; } bool crosspath(long k) { for (long i=1;i<=adjl[k][0];i++) { long j=adjl[k][i]; if (!used[j]) { used[j]=true; if (mat[j]==0 || crosspath(mat[j])) { mat[j]=k; return true; } } } return false; } void hungary() { for (long i=1;i<=n1;i++) { if (crosspath(i)) match++; memset(used,0,sizeof(used)); } } void print() { fprintf(fo,"%ld",match); fclose(fi); fclose(fo); } int main() { readfile(); hungary(); print(); return 0; }Horcroft-Karp
#include<stdio.h> #include<queue> #include<iostream> #include<string.h> #include<math.h> using namespace std; #define eps 1e-6 const int MAXN=3005; const int INF=1<<28; int g[MAXN][MAXN]; int Mx[MAXN],My[MAXN];// Mx[i]表示xi对应的匹配,My[i]表示yi对应的匹配. int Nx,Ny; int dx[MAXN],dy[MAXN],dis;// 层的概念,即在BFS中的第几层. bool vst[MAXN]; struct Node1 { int x,y,s; }guests[MAXN]; struct Node2 { int x,y; }um[MAXN]; double distance(Node1 a,Node2 b) { double x=a.x-b.x; double y=a.y-b.y; return sqrt(x*x+y*y); } /* 首先从所有X的未盖点进行BFS, BFS之后对每个X节点和Y节点维护距离标号, 如果Y节点是未盖点那么就找到了一条最短增广路, BFS完之后就找到了最短增广路集, 随后可以直接用DFS对所有允许弧(dist[y]=dist[x]+1, 可以参见高流推进HLPP的实现)进行类似于匈牙利中寻找增广路的操作, 这样就可以做到O(m)的复杂度。 */ bool searchP() { queue<int>Q; dis=INF; memset(dx,-1,sizeof(dx)); memset(dy,-1,sizeof(dy)); for(int i=0;i<Nx;i++) if(Mx[i]==-1)//将未匹配x集合中元素入队列 { Q.push(i); dx[i]=0; } while(!Q.empty()) { int u=Q.front(); Q.pop(); if(dx[u]>dis) break; for(int v=0;v<Ny;v++) if(g[u][v]&&dy[v]==-1) { dy[v]=dx[u]+1; if(My[v]==-1) dis=dy[v]; else { dx[My[v]]=dy[v]+1; Q.push(My[v]); } } } return dis!=INF; } bool DFS(int u) { for(int v=0;v<Ny;v++) if(!vst[v]&&g[u][v]&&dy[v]==dx[u]+1) { vst[v]=1; if(My[v]!=-1&&dy[v]==dis) continue; if(My[v]==-1||DFS(My[v])) { My[v]=u; Mx[u]=v; return 1; } } return 0; } int HK() { int res=0; memset(Mx,-1,sizeof(Mx)); memset(My,-1,sizeof(My)); while(searchP()) { memset(vst,0,sizeof(vst)); for(int i=0;i<Nx;i++) if(Mx[i]==-1&&DFS(i)) res++; } return res; } int main() { //freopen("test.in","r",stdin); //freopen("test.out","w",stdout); int n,m,t,i,j; int T,iCase=0; scanf("%d",&T); while(T--) { iCase++; scanf("%d",&t); scanf("%d",&m); for(i=0;i<m;i++) scanf("%d%d%d",&guests[i].x,&guests[i].y,&guests[i].s); scanf("%d",&n); for(i=0;i<n;i++) scanf("%d%d",&um[i].x,&um[i].y); Nx=m;Ny=n; memset(g,0,sizeof(g)); for(i=0;i<m;i++) { for(j=0;j<n;j++) { if(distance(guests[i],um[j])/guests[i].s-t<eps) { g[i][j]=1; } } } printf("Scenario #%d:\n%d\n\n",iCase,HK()); } return 0; }
二分图算法模板汇总
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。