poj 2195 KM

题意:小矮人回家,最小的花费

解法:KM模板题

先吐槽一下,多校,呵呵~

在吐槽一下, 这书上的代码貌似都是kuangbin的~囧,那你书上整对啊,书上都不对,哎

/*
----------------------------------

   Love is more than a word.
   It says so much.
   When I see these four letters,
   I almost feel your touch.
   This is only happened since
   I fell in love with you.
   Why this word does this,
   I haven't got a clue.

                   To My Goddess
                          CY
----------------------------------
*/

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 300+5

#define ull unsigned long long
 #define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
 #define REP(i,a,b) for(i=a;i<=b;i++)
  #define rep(i,n) for(i=0;i<n;i++)

#define cle(a) memset(a,0,sizeof(a))
 #define clehead(a) rep(i,maxn)a[i]=-1

/*
  The time of story :
  **  while(1)
    {
         once upon a time,
         there was a mountain,
         on top of which there was a temple,
         in which there was an old monk and a little monk.
         Old monk was telling stories inside the temple.
         What was he talking about?
  **  }

   ÎûÎû
   (*^__^*)
*/

#define sci(a) scanf("%d",&a)
 #define scd(a) scanf("%lf",&a)
  #define pri(a) printf("%d",a)
   #define prie(a) printf("%d\n",a)
    #define prd(a)  printf("%lf",a)
     #define prde(a) printf("%lf\n",a)
      #define pre printf("\n")

#define LL(x) x<<1
 #define RR(x) x<<|1

#define pb push_back
#define mod 90001
#define PI 3.141592657

const ull INF = 1LL << 61;
const int inf =   int(1e9)+10;
const double eps=1e-5;

using namespace std;

struct node
{
   int x,y;
};

bool cmp(int a,int b){
    return a>b;
}
int mat[maxn][maxn],match1[maxn],match2[maxn];
int km(int m,int n)
{
    int s[maxn],t[maxn],l1[maxn],l2[maxn],p,q,ret=0,i,j,k;
    rep(i,m){
        for(l1[i]=-inf,j=0;j<n;j++)l1[i]=mat[i][j]>l1[i]?mat[i][j]:l1[i];
        if(l1[i]==-inf)return -1;
    }
    for(i=0;i<n;l2[i++]=0);
    memset(match1,-1,sizeof(match1));
    memset(match2,-1,sizeof(match2));
    for(i=0;i<m;i++)
    {
        memset(t,-1,sizeof(t));
        for(s[p=q=0]=i;p<=q&&match1[i]<0;p++)
        {
            for(k=s[p],j=0;j<n&&match1[i]<0;j++)
            {
                if(l1[k]+l2[j]==mat[k][j]&&t[j]<0)
                {
                    s[++q]=match2[j],t[j]=k;
                    if(s[q]<0)
                    {
                        for(p=j;p>=0;j=p)
                        {
                            match2[j]=k=t[j],p=match1[k],match1[k]=j;
                        }
                    }
                }
            }
        }
                if(match1[i]<0)
                {
                    for(i--,p=inf,k=0;k<=q;k++)
                    {
                        for(j=0;j<n;j++)
                        {
                            if(t[j]<0&&l1[s[k]]+l2[j]-mat[s[k]][j]<p)
                            {
                                p=l1[s[k]]+l2[j]-mat[s[k]][j];
                            }
                        }
                    }
                    for(j=0;j<n;l2[j]+=t[j]<0?0:p,j++);
                    for(k=0;k<=q;l1[s[k++]]-=p);
                }

    }
    for(i=0;i<m;i++)
    {
        ret+=mat[i][match1[i]];
    }
    return ret;
}
int main()
{
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    int ip1,ip2;
    int n,m;
    node l[maxn];
    node r[maxn];
    while(cin>>n>>m)
    {
        if(n+m==0)break;
        int i,j,k;
        char c;
        ip1=ip2=0;
        rep(i,n){
           rep(j,m)
           {
               cin>>c;
               if(c=='m')
               {
                   l[ip1].x=i;
                   l[ip1++].y=j;
               }
               else if(c=='H'){
                   r[ip2].x=i;
                   r[ip2++].y=j;
               }
           }
        }
        rep(i,ip1){
           rep(j,ip2)
           {
               mat[i][j]=-(abs(l[i].x-r[j].x)+abs(l[i].y-r[j].y));
           }
        }
       // cout<<ip1<<":"<<ip2<<endl;
        cout<<-km(ip1,ip2)<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值