二分图如果是没有权值的,求最大匹配。则是用匈牙利算法求最大匹配。如果带了权值,求最大或者最小权匹配,则必须用KM算法。
其实最大和最小权匹配都是一样的问题。只要会求最大匹配,如果要求最小权匹配,则将权值取相反数,再把结果取相反数,那么最小权匹配就求出来了。
下面是几个模板:
1、匈牙利算法,例子是hdu2063
时间复杂度:O(VE)
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<queue> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef long long ll; typedef pair<int,int> PII; #define mod 1000000007 #define pb push_back #define mp make_pair #define all(x) (x).begin(),(x).end() #define fi first #define se second //head #define MAX 505 int line[MAX][MAX],used[MAX],nxt[MAX]; int k,n,m; bool Find(int x) { for(int i=1;i<=m;i++) { if(line[x][i]&&!used[i]) { used[i]=1; if(nxt[i]==0||Find(nxt[i])){ nxt[i]=x; return true; } } } return false; } int match() { int sum=0; for(int i=1;i<=n;i++) { memset(used,0,sizeof(used)); if(Find(i)) sum++; } return sum; } int main() { ios_base::sync_with_stdio(false); cin.tie(0); while(cin>>k) { if(k==0) break; memset(line,0,sizeof(line)); memset(nxt,0,sizeof(nxt)); cin>>n>>m; while(k--) { int u,v; cin>>u>>v; line[u][v]=1; } cout<<match()<<endl; } return 0; }