zoukankan      html  css  js  c++  java
  • KM模板题——pku2195

    View Code
    #include<stdio.h>
    #include
    <math.h>
    #include
    <string.h>

    #define MAXN 109
    #define inf 1000000000
    #define _clr(x) memset(x,0xff,sizeof(int)*MAXN)

    int mat[109][109];
    int match1[MAXN];
    int match2[MAXN];
    struct data
    {
    int fi,fj;
    }H[
    109];

    struct data1
    {
    int fi,fj;
    }M[
    109];



    int KM(int m,int n,int mat[][MAXN])
    {
    int s[MAXN],t[MAXN],l1[MAXN],l2[MAXN],p,q,ret=0,i,j,k;
    for (i=0;i<m;i++){
    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;没有匹配则返回-1
    }

    for (i=0;i<n;l2[i++]=0);
    for (_clr(match1),_clr(match2),i=0;i<m;i++){
    for (_clr(t),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()
    {
    int Mi,Mj;
    while(scanf("%d%d",&Mi,&Mj),Mi||Mj)
    {
    memset(H,
    0,sizeof(H));
    memset(M,
    0,sizeof(M));
    int i,j,addH=0,addM=0;
    char str;
    getchar();
    for(i=0;i<Mi;i++)
    {
    for(j=0;j<Mj;j++)
    {
    scanf(
    "%c",&str);

    if(str=='H')
    {
    H[addH].fi
    =i;
    H[addH].fj
    =j;
    addH
    ++;
    }
    else if(str=='m')
    {
    M[addM].fi
    =i;
    M[addM].fj
    =j;
    addM
    ++;
    }
    }
    getchar();
    }

    for(i=0;i<addM;i++)
    {
    for(j=0;j<addH;j++)
    {
    mat[i][j]
    =abs(M[i].fi-H[j].fi)+abs(M[i].fj-H[j].fj);
    mat[i][j]
    =-mat[i][j];//km是和最大的匹配,最小匹配时距离取反
    }
    }

    int count=-KM(addM,addH,mat);//距离是负数,取反为正
    printf("%d\n",count);

    }
    }

      

  • 相关阅读:
    plsqldeveloper永久注册码
    git常用命令
    淘淘中的一些环境的处理
    Hibernate查询
    markdown的学习
    npm如何发布一个自己的package
    聊聊font-family的那些事
    js 随机生成任意长度的字符串
    CSS世界(张鑫旭)系列学习总结 (四)盒尺寸四大家族
    CSS世界(张鑫旭)系列学习总结 (三)width和height作用的具体细节
  • 原文地址:https://www.cnblogs.com/huhuuu/p/2112863.html
Copyright © 2011-2022 走看看