您的位置:首页 > 其它

二分图最优匹配 模板

2017-11-30 21:39 399 查看
① 时间复杂度O(n^4)

#include <iostream>
#include <string.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000;
int cx[maxn],cy[maxn],w[maxn][maxn],usex[maxn],usey[maxn],girl[maxn];
int slack[maxn];
int m,n,ans;
bool find(int x)
{
usex[x]=1;
for (int i=1;i<=m;i++)
{
if (w[x][i]==cx[x]+cy[i]&&usey[i]==0)
{
usey[i]=1;
if (girl[i]==0||find(girl[i]))
{
girl[i]=x;
return true;
}
}
}
return false;
}
int km()
{
for (int i=1;i<=n;i++)
{
while (1)
{
memset(usex,0,sizeof(usex));
memset(usey,0,sizeof(usey));
int d=inf;
if (find(i))break;
for (int j=1;j<=n;j++)
{
if (usex[j])
{
for (int k=1;k<=m;k++)
if (!usey[k])
d=min(d,cx[j]+cy[k]-w[j][k]);
}
}
if (d==inf)return -1;
for (int j=1;j<=n;j++)
if (usex[j]) cx[j]-=d;
for (int j=1;j<=m;j++)
if (usey[j]) cy[j]+=d;
}
}
ans=0;
for (int i=1;i<=m;i++)
ans+=w[girl[i]][i];
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n>>m;
memset(cx,0,sizeof(cx));
memset(cy,0,sizeof(cy));
for (int i=1;i<=n;i++)
{
int d=0;
for (int j=1;j<=m;j++)
{
cin>>w[i][j];
d=max(d,w[i][j]);
}
cx[i]=d;
}
memset(girl,0,sizeof(girl));
cout<<km()<<endl;
return 0;
} 上面的return -1指的是不存在完全匹配;

②O(n^3)
#include <iostream>
#include <string.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1000;
int cx[maxn],cy[maxn],w[maxn][maxn],usex[maxn],usey[maxn],girl[maxn];
int slack[maxn];
int n,ans;
bool find(int x)
{
usex[x]=1;
for (int i=1;i<=n;i++)
{
if (usey[i])
continue;
int gap=cx[x]+cy[i]-w[x][i];
if (gap==0)
{
usey[i]=1;
if (girl[i]==0||find(girl[i]))
{
girl[i]=x;
return true;
}
}
else
slack[i]=min(slack[i],gap);
}
return false;
}
int km()
{
for (int i=1;i<=n;i++)
{
memset(slack,inf,sizeof(slack));
while (1)
{
memset(usex,0,sizeof(usex));
memset(usey,0,sizeof(usey));
int d=inf;
if (find(i))break;
for (int j=1;j<=n;j++)
if (!usey[j])
d=min(d,slack[j]);
if (d==inf)return -1;
for (int j=1;j<=n;j++)
{
if (usex[j]) cx[j]-=d;
if (usey[j]) cy[j]+=d;
else
slack[j]-=d;
}
}
}
ans=0;
for (int i=1;i<=n;i++)
ans+=w[girl[i]][i];
return ans;
}
int main()
{
std::ios::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
cin>>n;
memset(cx,0,sizeof(cx));
memset(cy,0,sizeof(cy));
for (int i=1;i<=n;i++)
{
int d=0;
for (int j=1;j<=n;j++)
{
cin>>w[i][j];
d=max(d,w[i][j]);
}
cx[i]=d;
}
memset(girl,0,sizeof(girl));
cout<<km()<<endl;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  图论