二分图的最大权匹配问题,而且这道题涉及到了要加点,最大权匹配要保证完全匹配的情况下才能得到值,否则dfs函数会一直进行下去,所以需要把原来的矩阵扩充为一个方阵
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define inf 0x7fffffff 5 #define N 205 6 #define max(x,y) x>y?x:y 7 #define min(x,y) x<y?x:y 8 using namespace std; 9 int map[N][N]; 10 bool usedx[N],usedy[N]; 11 int match[N]; 12 int lx[N],ly[N]; 13 int sta[N]; 14 int r,c; 15 bool dfs(int x) 16 { 17 int i,temp; 18 usedx[x]=true; 19 for(i=1;i<=c;i++) 20 { 21 temp=lx[x]+ly[i]-map[x][i]; 22 if(!usedy[i]&&temp==0) 23 { 24 usedy[i]=true; 25 if(match[i]==-1||dfs(match[i])) 26 { 27 match[i]=x; 28 return true; 29 } 30 } 31 else if(sta[i]>temp) 32 sta[i]=temp; 33 } 34 return false; 35 } 36 int km() 37 { 38 int i,j,k,d; 39 memset(lx,0,sizeof(lx)); 40 memset(ly,0,sizeof(ly)); 41 memset(match,-1,sizeof(match)); 42 for(i=1;i<=r;i++) 43 for(j=1;j<=c;j++) 44 lx[i]=max(lx[i],map[i][j]); 45 for(i=1;i<=r;i++) 46 { 47 while(1) 48 { 49 memset(usedx,0,sizeof(usedx)); 50 memset(usedy,0,sizeof(usedy)); 51 for(j=1;j<=c;j++) 52 sta[j]=inf; 53 if(dfs(i)) 54 break; 55 d=inf; 56 for(j=1;j<=c;j++) 57 if(!usedy[j]) 58 d=min(sta[j],d); 59 for(j=1;j<=r;j++) 60 if(usedx[j]) 61 lx[j]-=d; 62 for(j=1;j<=c;j++) 63 if(usedy[j]) 64 ly[j]+=d; 65 } 66 } 67 int res=0; 68 for(i=1;i<=c;i++) 69 if(match[i]!=-1) 70 res+=map[match[i]][i]; 71 return res; 72 } 73 int main() 74 { 75 int i,j; 76 while(scanf("%d%d",&r,&c)!=EOF) 77 { 78 memset(map,0,sizeof(map)); 79 for(i=1;i<=r;i++) 80 for(j=1;j<=c;j++) 81 scanf("%d",&map[i][j]); 82 r=max(r,c);//扩充为方阵 83 c=max(r,c); 84 printf("%d\n",km()); 85 } 86 return 0; 87 }