KM算法板子2

来源:互联网 发布:武汉网络推广外包 编辑:程序博客网 时间:2024/06/05 05:56

//HDU2426

//

#include <iostream>#include<stdio.h>#include<string.h>#include<string>using namespace std;const int maxn=550;int visx[maxn],visy[maxn];int link[maxn];int lx[maxn],ly[maxn];int w[maxn][maxn];int slack[maxn];int link1[maxn];int n,m;const int inf=999999999;int find(int x){    visx[x]=1;    for(int i=0;i<m;i++)    {        if(w[x][i]==inf||visy[i])            continue;        int t=lx[x]+ly[i]-w[x][i];        if(t==0)        {            visy[i]=1;            if(link[i]==-1||find(link[i]))            {                link[i]=x;                link1[x]=i;                return 1;            }        }        else        {            if(slack[i]>t)                slack[i]=t;        }    }    return 0;}int sk(){    memset(link,-1,sizeof(link));    memset(link1,-1,sizeof(link1));    memset(ly,0,sizeof(ly));    for(int i=0;i<n;i++)    {        lx[i]=-inf;        for(int j=0;j<m;j++)        {            if(w[i][j]!=inf)                lx[i]=max(lx[i],w[i][j]);        }    }    for(int i=0;i<n;i++)    {        //cout<<"m:"<<i<<endl;        for(int j=0;j<m;j++)            slack[j]=inf;        while(true)        {            memset(visx,0,sizeof(visx));            memset(visy,0,sizeof(visy));            if(find(i))                break;           // cout<<"sb"<<endl;            int d=inf;                       for(int j=0;j<m;j++)            {                if(!visy[j]&&d>slack[j])                    d=slack[j];            }             if(d==inf)               return -1;            for(int j=0;j<n;j++)            {                if(visx[j])                    lx[j]-=d;            }            for(int j=0;j<m;j++)            {                if(visy[j])                    ly[j]+=d;                else                {                   slack[j]-=d;                }            }        }    }    int ans=0;    int flag=0;    for(int i=0;i<n;i++)    {        if(link1[i]==-1)        {            flag=1;            break;        }        else        {            ans+=w[i][link1[i]];           // cout<<"ans"<<ans<<endl;        }    }    if(flag)     ans=-1;    return ans;}int main(){    int e;    int tot=1;    while(scanf("%d%d%d",&n,&m,&e)!=EOF)    {        for(int i=0;i<n;i++)        {            for(int j=0;j<m;j++)                w[i][j]=inf;        }        for(int i=1;i<=e;i++)        {            int a,b,c;            scanf("%d%d%d",&a,&b,&c);            if(c>=0)            {                w[a][b]=c;              //  w[a][b]=c;            }        }        printf("Case %d: %d\n",tot++,sk());    }    return 0;}


0 0