hdu2813 One fihgt one (KM最小权值和)

来源:互联网 发布:sodu源码zip 编辑:程序博客网 时间:2024/05/17 23:05

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2813


题解:KM模版题


#include <stdio.h>          #include <string.h>         #include <math.h>   #define INF 0x3f3f3f3f      #define MAXN 201    int w[MAXN][MAXN],match[MAXN];        int lx[MAXN],ly[MAXN],slack[MAXN];        int visitx[MAXN],visity[MAXN];int nx,ny;char LvBu[MAXN][21],CaoCao[MAXN][21];int find(int x)    {      int i,temp;      visitx[x]=1;      for(i=1;i<=ny;++i)      {      if(visity[i])      continue;      temp=lx[x]+ly[i]-w[x][i];      if(temp==0)      {      visity[i]=1;      if(match[i]==-1||find(match[i]))      {      match[i]=x;      return 1;      }      }      else if(slack[i]>temp)      {      slack[i]=temp;      }      }      return 0;      }      int KM()      {      int i,j,d,ans;      memset(ly,0,sizeof(ly));      memset(match,-1,sizeof(match));      for(i=1;i<=nx;++i)      {//lx初始化为与它关联边中最大的      lx[i]=w[i][1];      for(j=2;j<=ny;++j)      if(w[i][j]>lx[i])      lx[i]=w[i][j];      }      for(i=1;i<=nx;++i)      {      for(j=1;j<=ny;++j)      slack[j]=INF;      while(1)      {      memset(visitx,0,sizeof(visitx));      memset(visity,0,sizeof(visity));      if(find(i))      break;      d=INF;      for(j=1;j<=ny;++j)      {      if(!visity[j]&&d>slack[j])      d=slack[j];      }      for(j=1;j<=nx;++j)      {      if(visitx[j])      lx[j]-=d;      }      for(j=1;j<=ny;++j)      {      if(visity[j])      ly[j]+=d;      else      slack[j]-=d;      }      }      }      ans=0;        for(i=1;i<=ny;++i)      {      if(match[i]!=-1)   ans+=w[match[i]][i];     }  return ans;    } int check(char *s,int flag){int i;if(flag){for(i=1;i<MAXN;++i){if(strcmp(LvBu[i],s)==0)return i;if(strcmp(LvBu[i],"")==0){strcpy(LvBu[i],s);return i;}}}else{for(i=1;i<MAXN;++i){if(strcmp(CaoCao[i],s)==0)return i;if(strcmp(CaoCao[i],"")==0){strcpy(CaoCao[i],s);return i;}}}} int main(){int i,j,k,ans,val,x,y;char str1[21],str2[21];while(scanf("%d %d %d",&nx,&ny,&k)!=EOF){memset(LvBu,'\0',sizeof(LvBu));memset(CaoCao,'\0',sizeof(CaoCao));for(i=1;i<=nx;++i){for(j=1;j<=ny;++j)w[i][j]=(~INF+1);}while(k--){scanf("%s %s %d",str1,str2,&val);x=check(str1,1);y=check(str2,0);w[x][y]=(~val+1);//取反}ans=KM();printf("%d\n",(~ans+1));}return 0;}