hdu 2255 二分图带权匹配 模板题

来源:互联网 发布:在线网络理财排行榜 编辑:程序博客网 时间:2024/06/05 20:42

模板+注解在 http://blog.csdn.net/u011026968/article/details/38276945


hdu 2255 代码:

//KM×î´ó×îСƥÅä#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>using namespace std;#define INF 0x0fffffffconst int MAXN = 300+10;int n,match[MAXN];bool sx[MAXN],sy[MAXN];int lx[MAXN],ly[MAXN],mat[MAXN][MAXN];bool path(int u){    sx[u]=true;    for(int v=0;v<n;v++)        if(!sy[v] && lx[u]+ly[v]==mat[u][v])        {            sy[v]=true;            if(match[v] == -1 || path(match[v]))            {                match[v]=u;                return true;            }        }    return false;}int KM(){    for(int i=0;i<n;i++)    {        lx[i]=-INF;        ly[i]=0;        for(int j=0;j<n;j++)            lx[i]=max(lx[i], mat[i][j]);    }    memset(match, -1, sizeof(match));    for(int u=0;u<n;u++)        while(1)        {            memset(sx,0,sizeof(sx));            memset(sy,0,sizeof(sy));            if(path(u))break;            int dmin=INF;            for(int i=0;i<n;i++)                if(sx[i])                    for(int j=0;j<n;j++)                        if(!sy[j])                            dmin=min(lx[i]+ly[j]-mat[i][j],dmin);            for(int i=0;i<n;i++)            {                if(sx[i])                    lx[i]-=dmin;                if(sy[i])                    ly[i]+=dmin;            }        }    int sum=0;    for(int j=0;j<n;j++)        sum+=mat[match[j]][j];        //if(mat[match[j]][j])    return sum;}int main(){    //freopen("hdu2255.txt","r",stdin);    while(~scanf("%d",&n))    {        ////init()??        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)                mat[i][j]=INF;        for(int i=0;i<n;i++)            for(int j=0;j<n;j++)            {                scanf("%d",&mat[i][j]);            }        printf("%d\n",KM());    }    return 0;}


1 0
原创粉丝点击