POJ2195 最佳匹配

来源:互联网 发布:linux建站面板 编辑:程序博客网 时间:2024/05/13 10:18

题目意思:

        给定N个房子,以及N个人所在的位置,求如何走,使得所走的总距离最短。

        测试案例: 给定 N*M 的矩阵,矩阵是由 ‘H’(房子),‘m’(人), '.'(空地) 构成的。

思路:将图中的房子以及人取出来重新构图,构成一个二分图,然后求这个二分图的最佳匹配。

分别建立 容器(数组,向量等)来放置 房子,以及人,然后算出 每个人和每个房子之间的距离,记录在w数组里面,然后利用最佳匹配进行求解。

下面是我的代码:

#include<iostream>#include<vector>using namespace std;const int INTMAX=501;const int INF=10000;char map[INTMAX][INTMAX];int w[INTMAX][INTMAX];bool visitx[INTMAX];bool visity[INTMAX];int lx[INTMAX];int ly[INTMAX];int match[INTMAX];int n,m;typedef struct NODE{int x,y;}Node;vector<Node> house;vector<Node> man;int dfs(int t){    int i,tmp;    visitx[t]=true;    for(i=1;i<=house.size();i++){        if(!visity[i] && lx[t]+ly[i]==w[t][i]){            tmp=match[i];            visity[i]=true;            match[i]=t;            if(tmp==0 || dfs(tmp)) return 1;            match[i]=tmp;        }     }    return 0;}void BestMatch(){      int i,j,k;        memset(lx,INF,sizeof(lx));        memset(ly,0,sizeof(ly));        for(i=1;i<=man.size();i++){            for(j=1;j<=house.size();j++){                if(w[i][j]<lx[i]) lx[i]=w[i][j];            }                                              }        memset(match,0,sizeof(match));        for(i=1;i<=man.size();i++){//            while(1){                memset(visitx,0,sizeof(visitx));                memset(visity,0,sizeof(visity));                int min=10000000;                if(dfs(i)) break;                for(j=1;j<=man.size();j++){                    if(visitx[j])                               for(k=1;k<=house.size();k++){                        if(!visity[k] && w[j][k]-lx[j]-ly[k]<min)                            min=w[j][k]-lx[j]-ly[k];                             }                                                           }                for(j=1;j<=man.size();j++) if(visitx[j]) lx[j]+=min;                for(j=1;j<=house.size();j++)if(visity[j]) ly[j]-=min;             }        }}int main(){int n,m,i,j,ans;Node node;while(scanf("%d%d",&n,&m)!=EOF){if(n+m==0)break;house.clear();man.clear();for(i=0;i<n;i++){getchar();for(j=0;j<m;j++){scanf("%c",&map[i][j]);}}for(i=0;i<n;i++)for(j=0;j<m;j++){node.x=i;node.y=j;if(map[i][j]=='H'){house.push_back(node);}else if(map[i][j]=='m'){man.push_back(node);}}for(i=1;i<=man.size();i++)for(j=1;j<=house.size();j++)w[i][j]=abs(man[i-1].x-house[j-1].x)+abs(man[i-1].y-house[j-1].y);     BestMatch(); ans=0; for(i=1;i<=house.size();i++)ans=ans+w[match[i]][i]; printf("%d\n",ans);}return 0;}


 

 

原创粉丝点击