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 }

 

posted @ 2019-09-16 20:06  古比  阅读(155)  评论(0编辑  收藏  举报