HDU 2813 One fihgt one KM小变形

来源:互联网 发布:php环境变量 编辑:程序博客网 时间:2024/05/16 08:59

题意:吕布和曹操分别有n,m个武将,现在给你一些武将交战吕布家武将受伤情况,求受到的伤害最小值。


想法:建立负权边,KM模板,注意是吕布方受伤情况。

还有一点要注意的这里的inf不要定义为int型的最大值,那样会wa


#include<iostream>#include<cstdio>#include<cstring>#include<map>#define inf 1<<20using namespace std;const int nodes=200+5;int n,m,k;map<string,int>Mp;int mapp[nodes][nodes],linkerx[nodes],linkery[nodes],visx[nodes],visy[nodes],x[nodes],y[nodes];int slack[nodes];int dfs(int u){    visx[u]=1;    for(int i=1;i<=m;i++)    {        if(visy[i]) continue;        int fu=x[u]+y[i]-mapp[u][i];        if(!fu)        {            visy[i]=1;            if(linkery[i]==-1||dfs(linkery[i]))            {                linkery[i]=u;                linkerx[u]=i;                return 1;            }        }        else if(fu<slack[i])        slack[i]=fu;    }    return 0;}int Max(int a,int b){    if(a>b) return a;    return b;}void KM(){    for(int i=1;i<=n;i++)    {        x[i]=-inf;        for(int j=1;j<=m;j++)        {            x[i]=Max(x[i],mapp[i][j]);        }    }    memset(y,0,sizeof(y));    memset(linkerx,-1,sizeof(linkerx));    memset(linkery,-1,sizeof(linkery));    for(int i=1;i<=n;i++)    {        for(int j=1;j<=m;j++)        slack[j]=inf;        while(1)        {            memset(visx,0,sizeof(visx));            memset(visy,0,sizeof(visy));            if(dfs(i)) break;            int tmp=inf;            for(int j=1;j<=m;j++)            {                if(!visy[j]&&tmp>slack[j])                {                    tmp=slack[j];                }            }            for(int j=1;j<=n;j++)            {                if(visx[j]) x[j]-=tmp;            }            for(int j=1;j<=m;j++)            {                if(visy[j]) y[j]+=tmp;                else slack[j]-=tmp;            }        }    }}int main(){    while(~scanf("%d%d%d",&n,&m,&k))    {        int num1=0,num2=0;        for(int i=1;i<=n;i++)        {            for(int j=1;j<=m;j++)            {                mapp[i][j]=-inf;            }        }        Mp.clear();        for(int i=1;i<=k;i++)        {            char a[25],b[25];            int w;            scanf("%s%s%d",a,b,&w);            if(Mp[a]==0) Mp[a]=++num1;            if(Mp[b]==0) Mp[b]=++num2;            mapp[Mp[a]][Mp[b]]=-w;        }        KM();        int sum=0;        for(int i=1;i<=n;i++)        {            sum+=mapp[i][linkerx[i]];        }        printf("%d\n",-sum);    }    return 0;}


0 0