【KM】POJ2195/HDU1533-Going home

//最近没什么时间quq据说长得帅的人都在切八中,然而长得丑的人只能水水裸题

【题目大意】

给出一张地图及人和房屋的位置,求出每个人回到不同房屋所具有的最小代价和。

【思路】

最小权匹配,先O(n^2)求出每个人到任意房屋的距离后取反,就变成了裸的KM。数据范围很小,O(n^4)可以0ms过。

【错误点】

1.slack在每次循环中药重新设置为无穷大。2.内循环和外循环的循环变量重名了。3.变量名取太乱了用错了一次。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<cmath>
  5 #include<algorithm>
  6 using namespace std;
  7 const int INF=0x7fffffff;
  8 const int MAXN=500;
  9 int n,m;
 10 int mx[MAXN],my[MAXN],hx[MAXN],hy[MAXN],numm,numh;
 11 int g[MAXN][MAXN];
 12 int visx[MAXN],visy[MAXN],fx[MAXN],fy[MAXN],slack[MAXN],lk[MAXN];
 13 
 14 int Hungary_dfs(int u)
 15 {
 16     visx[u]=1;
 17     for (int i=1;i<=numm;i++)
 18     {
 19         int wt=fx[u]+fy[i]-g[u][i];
 20         if (!visy[i] && wt==0)
 21         {
 22             visy[i]=1;
 23             if (lk[i]==-1 || Hungary_dfs(lk[i]))
 24             {
 25                 lk[i]=u;
 26                 return 1;
 27             }
 28         }
 29         else if (wt<slack[i]) slack[i]=wt; 
 30     }
 31     return 0;
 32 }
 33 
 34 int KM()
 35 {
 36     memset(lk,-1,sizeof(lk));
 37     for (int i=1;i<=numm;i++)
 38     {
 39         fx[i]=-INF;
 40         fy[i]=0;
 41         for (int j=1;j<=numm;j++) fx[i]=max(fx[i],g[i][j]);
 42     }
 43     
 44     for (int i=1;i<=numm;i++)
 45     {
 46         memset(visx,0,sizeof(visx));
 47         memset(visy,0,sizeof(visy));
 48         memset(slack,127,sizeof(slack));//slack每次都要初始化为无穷大 
 49         while (!Hungary_dfs(i))
 50         {
 51             int delta=INF;
 52             for (int j=1;j<=numm;j++) if (!visy[j]) delta=min(delta,slack[j]);
 53             for (int j=1;j<=numm;j++)//这里忘掉了外面还套了一重循环,重复用了i! 
 54             {
 55                 if (visx[j])
 56                 {
 57                     visx[j]=0;
 58                     fx[j]-=delta;
 59                 } 
 60                 if (visy[j])
 61                 {
 62                     visy[j]=0;
 63                     fy[j]+=delta;
 64                 }
 65             }
 66         }
 67     }
 68     
 69     int ret=0; 
 70     for (int i=1;i<=numm;i++) ret+=fx[i]+fy[i];//这里numm写成了n 
 71     return ret;
 72 }
 73 
 74 void init()
 75 {
 76     numm=numh=0;
 77     for (int i=0;i<n;i++)
 78     {
 79         char c;
 80         getchar();
 81         for (int j=0;j<m;j++)
 82         {
 83             scanf("%c",&c);
 84             if (c=='m') 
 85             {
 86                 mx[++numm]=i;
 87                 my[numm]=j;
 88             }
 89             else if (c=='H')
 90             {
 91                 hx[++numh]=i;
 92                 hy[numh]=j;
 93             } 
 94         }
 95     }
 96     for (int i=1;i<=numm;i++)
 97         for (int j=1;j<=numh;j++)
 98         {
 99             g[i][j]=-1*(abs(mx[i]-hx[j])+abs(my[i]-hy[j]));
100         }
101 }
102 
103 int main()
104 {
105     while (scanf("%d%d",&n,&m))
106     {
107         if (n==m && m==0) break;
108         init();
109         cout<<KM()*(-1)<<endl;
110     }
111     return 0;
112 } 

 

posted @ 2016-04-05 23:20  iiyiyi  阅读(182)  评论(0编辑  收藏  举报