KM算法求的是二分图最优匹配,权值最大。当让求权值最小时,只需把原来的权值都改成负值即可,,其他的都不用变。。。。。。。。。题目:
Time Limit:1000MS | Memory Limit:65536K | |
Total Submissions:12101 | Accepted:6261 |
Description
Your task is to compute the minimum amount of money you need to pay in order to send these n little men into those n different houses. The input is a map of the scenario, a '.' means an empty space, an 'H' represents a house on that point, and am 'm' indicates there is a little man on that point.
![](https://i-blog.csdnimg.cn/blog_migrate/29da4c22cd9a35eb96b2a08b75ce8420.jpeg)
You can think of each point on the grid map as a quite large square, so it can hold n little men at the same time; also, it is okay if a little man steps on a grid with a house without entering that house.
Input
Output
Sample Input
2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0
Sample Output
2 10 28ac代码:
#include <iostream> #include <string.h> #include <algorithm> #include <cstdio> #include <cmath> using namespace std; int n,m; const int mn=105; int sx[mn],sy[mn],vx[mn],vy[mn],matchx[mn]; char map[mn][mn]; int length[mn][mn]; int countt,num; int slack[mn]; struct house{ int x,y; }hh[mn]; struct men{ int x,y; }mm[mn]; void chushihua(){ countt=0; num=0; for(int i=1;i<=n;++i){ for(int j=1;j<=m;++j){ cin>>map[i][j]; if(map[i][j]=='H'){ hh[countt].x=i; hh[countt].y=j; countt++; } if(map[i][j]=='m'){ mm[num].x=i; mm[num].y=j; num++; } } } for(int i=0;i<countt;++i){ sy[i]=0;sx[i]=INT_MIN; for(int j=0;j<num;++j){ length[i][j]=0-((abs(hh[i].x-mm[j].x))+(abs(hh[i].y-mm[j].y))); //printf("%d\n",length[i][j]); if(length[i][j]>sx[i]) sx[i]=length[i][j]; } } } bool dfs(int x){ vx[x]=1; for(int i=0;i<num;++i){ int xx=sx[x]+sy[i]-length[x][i]; if(!vy[i]&&xx==0){ vy[i]=1; if(matchx[i]==-1||dfs(matchx[i])){ matchx[i]=x; //printf("x=%d i=%d\n",x,i); return true; } } else if(slack[i]>xx) slack[i]=xx; } return false; } void bestmatch(){ for(int i=0;i<countt;++i){ while(1){ memset(vx,0,sizeof(vx)); memset(vy,0,sizeof(vy)); for(int j=0;j<countt;++j) slack[j]=INT_MAX; if(dfs(i)) break; int dd=INT_MAX; for(int j=0;j<countt;++j){ if(!vy[j]&&slack[j]<dd) dd=slack[j]; } for(int j=0;j<countt;++j) { if(vx[j]) sx[j]-=dd; if(vy[j]) sy[j]+=dd; } } } } int main(){ while(scanf("%d%d",&n,&m)&&n&&m){ memset(sx,0,sizeof(sx)); memset(sy,0,sizeof(sy)); memset(matchx,-1,sizeof(matchx)); memset(length,0,sizeof(length)); memset(map,'0',sizeof(map)); memset(slack,0,sizeof(slack)); chushihua(); bestmatch(); int sum=0; for(int i=0;i<countt;++i) {/*printf("%d ",length[matchx[i]][i]);*/sum+=(0-length[matchx[i]][i]);} printf("%d\n",sum); } return 0; }