KM poj 2195
题意:给出一个地图,地图上有人和房子,问如何分配哪个人去哪个房子,走的路最短?
这道题是个完备匹配的情况下,问怎么才能走的路最少,可以用KM来做。
只不过KM算法是用来求解最大最优值,所以我们得改一下数据,将每个人去房子的路程都改为负数。
最后再得出 -KM()即刻
1 #include<cstdio> 2 #include<algorithm> 3 #include<string.h> 4 #include<math.h> 5 #include<iostream> 6 using namespace std; 7 const int maxn=1e2+10; 8 const int inf=0x3f3f3f3f; 9 int lx[maxn],ly[maxn]; 10 int match[maxn]; 11 int visx[maxn],visy[maxn]; 12 struct node 13 { 14 int x,y; 15 }a[maxn],b[maxn]; 16 int G[maxn][maxn]; 17 int numa,numb; 18 int dfs(int k) 19 { 20 visx[k]=1; 21 for(int i=1;i<=numa;i++){ 22 if(!visy[i]&&G[k][i]==lx[k]+ly[i]){ 23 visy[i]=1; 24 if(!match[i]||dfs(match[i])){ 25 match[i]=k; 26 return 1; 27 } 28 } 29 } 30 return 0; 31 } 32 int KM() 33 { 34 for(int i=1;i<=numa;i++){ 35 lx[i]=-inf,ly[i]=0; 36 for(int j=1;j<=numa;j++) 37 lx[i]=max(lx[i],G[i][j]); 38 } 39 for(int k=1;k<=numa;k++){ 40 while(1){ 41 memset(visx,0,sizeof(visx)); 42 memset(visy,0,sizeof(visy)); 43 if(dfs(k)) break; 44 int mn=inf; 45 46 for(int i=1;i<=numa;i++) if(visx[i]) 47 for(int j=1;j<=numa;j++) if(!visy[j]) 48 mn=min(mn,lx[i]+ly[j]-G[i][j]); 49 if(mn==inf) return -1; 50 for(int i=1;i<=numa;i++) if(visx[i]) lx[i]-=mn; 51 for(int i=1;i<=numa;i++) if(visy[i]) ly[i]+=mn; 52 } 53 } 54 int ans=0; 55 for(int i=1;i<=numa;i++) 56 if(match[i]) 57 ans+=G[match[i]][i]; 58 return ans; 59 } 60 void init() 61 { 62 numa=numb=0; 63 memset(match,0,sizeof(match)); 64 memset(G,0,sizeof(G)); 65 } 66 int main() 67 { 68 int n,m; 69 while(scanf("%d%d",&n,&m)!=EOF){ 70 if(n==0&&m==0) break; 71 init(); 72 char t; 73 for(int i=0;i<n;i++){ 74 for(int j=0;j<m;j++){ 75 cin>>t; 76 if(t=='H'){ 77 numa++; 78 a[numa].x=i; 79 a[numa].y=j; 80 } 81 else if(t=='m'){ 82 numb++; 83 b[numb].x=i; 84 b[numb].y=j; 85 } 86 } 87 } 88 for(int i=1;i<=numa;i++){ 89 int x1=a[i].x,y1=a[i].y; 90 for(int j=1;j<=numb;j++){ 91 int x2=b[j].x,y2=b[j].y; 92 int w=fabs(x1-x2)+fabs(y1-y2); 93 G[i][j]=-w; 94 } 95 } 96 printf("%d\n",-KM()); 97 } 98 return 0; 99 }