二分图最优匹配 模板

来源:互联网 发布:activity之间数据传递 编辑:程序博客网 时间:2024/05/17 22:18

① 时间复杂度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;}}elseslack[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;} 




原创粉丝点击