带权的完备二分匹配问题

来源:互联网 发布:淘宝苹果数据线 编辑:程序博客网 时间:2024/06/06 13:07

啦啦啦啦,学算法了。

自己其实还是有些不懂的,但先记下来为敬好吧,没毛病;

模板 http://blog.csdn.net/ZYY173533832/article/details/11519291?locationNum=7&fps=1

思想 http://blog.csdn.net/u013044116/article/details/45228057?locationNum=4&fps=1

上个自己版本的高仿hdu2255,裸模板;

#include <iostream>#include<stdio.h>#include<algorithm>#include<string.h>using namespace std;const int maxn=310;int map[310][310];int n,slack[310];int lx[310],ly[310],link[310];bool visx[310],visy[310];const int inf=999999;bool dfs(int x){   visx[x]=true;   for(int y=1;y<=n;y++)   {       if(visy[y]) continue;       int t=lx[x]+ly[y]-map[x][y];       if(t==0)       {           visy[y]=true;           if(link[y]==-1||dfs(link[y]))           {               link[y]=x;               return true;           }       }       else if(slack[y]>t)       {           slack[y]=t;       }   }   return false;}int km(){    memset(link,-1,sizeof(link));    memset(lx,0,sizeof(lx));    memset(ly,0,sizeof(ly));    for(int i=1;i<=n;i++)    {      for(int j=1;j<=n;j++)        {          if(lx[i]<map[i][j])              lx[i]=map[i][j];        }    }    for(int i=1;i<=n;i++)    {      for(int j=1;j<=n;j++) slack[j]=inf;      while(1)      {        memset(visx,false,sizeof(visx));        memset(visy,false,sizeof(visy));        if(dfs(i)) break;        int d=inf;        for(int j=1;j<=n;j++)        {            if(!visy[j]&&d>slack[j])            {                d=slack[j];            }        }        for(int j=1;j<=n;j++)        {            if(visx[j]) lx[j]-=d;        }        for(int j=1;j<=n;j++)        {            if(visy[j]) ly[j]+=d;            else slack[j]-=d;        }      }    }    int ans=0;    for(int i = 1; i <= n ; i ++)        ans += map[link[i]][i];    return ans;}int main(){    while(scanf("%d",&n)!=EOF)    {        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                scanf("%d",&map[i][j]);            }        }        printf("%d\n",km());    }    return 0;}

0 0
原创粉丝点击