首页 > 编程知识 正文

二分最大匹配复杂度,的最大匹配算法

时间:2023-05-04 07:15:05 阅读:254743 作者:4073

二分图最大匹配是寻找最大匹配数,用匈牙利算法。当连接的边带有权值时,要寻找匹配后权值和最大的方案,且保证A集合中的点均有B中的点能匹配。此时问题就转化为二分图最大权完美匹配。

KM算法核心为:为每一点添加顶标,在顶标的限制下用匈牙利算法处理出最大匹配数,若最大匹配数=n,则达到最优解,输出。否则修改顶标,再用匈牙利算法处理,如此重复。

时间复杂度:O(n3)

参考:二分图最大权完美匹配 题解
(转载模板)
【模板】二分图最大权完美匹配

#include<bits/stdc++.h>#define ll long long#define IOS std::ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);#define Rep(i,l,r) for(int i=(l);i<=(r);i++)using namespace std;template<typename T>//边权的类型struct KM{ const T INF = 1e18; static const int N = 500; int mb[N+7],vb[N+7],p[N+7]; //注意,mb表示:完美匹配下与右部第i个点相匹配的**左部点的编号**. T ka[N+7],kb[N+7],c[N+7],e[N+7][N+7]; void init(int n){ for(int a=1;a<=n;a++){ for(int b=1;b<=n;b++){ e[a][b]=-INF; } } } void add(int u,int v,T w){ e[u][v]=max(e[u][v],w); } void Bfs(int u,int n){ int a,v=0,vl=0; T d; for(int i=1;i<=n;i++){p[i]=0;c[i]=INF;} mb[v]=u; do { a=mb[v],d=INF,vb[v]=1; for(int b=1;b<=n;b++)if(!vb[b]){ if(c[b]>ka[a]+kb[b]-e[a][b]) c[b]=ka[a]+kb[b]-e[a][b],p[b]=v; if(c[b]<d) d=c[b],vl=b; } for(int b=0;b<=n;b++) if(vb[b]) ka[mb[b]]-=d,kb[b]+=d; else c[b]-=d; v=vl; } while(mb[v]); while(v) mb[v]=mb[p[v]],v=p[v]; } T km(int n){ for(int i=1;i<=n;i++) mb[i]=ka[i]=kb[i]=0; for(int a=1;a<=n;a++){ for(int b=1;b<=n;b++) vb[b]=0; Bfs(a,n); } T res=0; for(int b=1;b<=n;b++) res+=e[mb[b]][b]; return res; }};int n,m;KM<ll>km;//Main//左右n个节点,m条边带权边//输入n,m和m条边int main(){ IOS cin>>n>>m; km.init(n);for(int i=1;i<=m;i++){ll u,v; double w;//m条带权边 cin>>u>>v>>w;km.add(u,v,w);}printf("%lldn",km.km(n));for(int u=1;u<=n;u++) printf("%d ",km.mb[u]);puts("");return 0;}

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。