zoukankan      html  css  js  c++  java
  • POJ2195 Going Home 最佳完美匹配

      题目链接:http://poj.org/problem?id=2195

      最佳完美匹配裸题,直接用KM算法求就可以了。

      KM算法就是维护每个点的可行顶标,即始终有 l(x)+l(y)>=w(x,y)(求最大)、l(x)+l(y)<=w(x,y)(求最小),然后依次加边,求最大匹配,直到匹配是完美匹配即可。

      1 //STATUS:G++_AC_0MS_764KB
      2 #include<stdio.h>
      3 #include<stdlib.h>
      4 #include<string.h>
      5 #include<math.h>
      6 #include<iostream>
      7 #include<string>
      8 #include<algorithm>
      9 #include<vector>
     10 #include<queue>
     11 #include<stack>
     12 using namespace std;
     13 #define LL long long
     14 #define Max(a,b) ((a)>(b)?(a):(b))
     15 #define Min(a,b) ((a)<(b)?(a):(b))
     16 #define mem(a,b) memset(a,b,sizeof(a))
     17 #define lson l,mid,rt<<1
     18 #define rson mid+1,r,rt<<1|1
     19 const int MAX=110,INF=200000000;
     20 
     21 struct Node{
     22     int x,y;
     23 }H[MAX],M[MAX];
     24 
     25 char map[MAX][MAX];
     26 int w[MAX][MAX],lx[MAX],ly[MAX],S[MAX],T[MAX],y[MAX];
     27 int n,m,k1,k2;
     28 
     29 int dfs(int u)
     30 {
     31     S[u]=1;
     32     int v;
     33     for(v=0;v<k1;v++){
     34         if(w[u][v]==lx[u]+ly[v] && !T[v]){
     35             T[v]=1;
     36             if(y[v]==-1 || dfs(y[v])){
     37                 y[v]=u;
     38                 return 1;
     39             }
     40         }
     41     }
     42     return 0;
     43 }
     44 
     45 void update()
     46 {
     47     int i,j,min;
     48     min=INF;
     49     for(i=0;i<k1;i++)if(S[i])
     50         for(j=0;j<k1;j++)if(!T[j])
     51             min=Min(min,w[i][j]-lx[i]-ly[j]);
     52     for(i=0;i<k1;i++){
     53         if(S[i])lx[i]+=min;
     54         if(T[i])ly[i]-=min;
     55     }
     56 }
     57 
     58 void KM()
     59 {
     60     mem(y,-1);
     61     mem(ly,0);
     62     int i,j;
     63     for(i=0;i<k1;i++){
     64         lx[i]=INF;
     65         for(j=0;j<k1;j++)
     66             if(w[i][j]<lx[i])lx[i]=w[i][j];
     67     }
     68     for(i=0;i<k1;i++){
     69         while(1){
     70             mem(S,0);mem(T,0);
     71             if(dfs(i))break;
     72             update();
     73         }
     74     }
     75 }
     76 
     77 int main()
     78 {
     79 //    freopen("in.txt","r",stdin);
     80     int i,j,ans;
     81     while(~scanf("%d%d",&n,&m) && n&&m)
     82     {
     83         ans=k1=k2=0;
     84         mem(w,0);
     85         for(i=0;i<n;i++){
     86             scanf("%s",map[i]);
     87             for(j=0;j<m;j++){
     88                 if(map[i][j]=='m')
     89                     M[k1].x=i,M[k1++].y=j;
     90                 if(map[i][j]=='H')
     91                     H[k2].x=i,H[k2++].y=j;
     92             }
     93         }
     94         for(i=0;i<k1;i++)
     95             for(j=0;j<k1;j++)
     96                 w[i][j]=abs(M[i].x-H[j].x)+abs(M[i].y-H[j].y);
     97 
     98         KM();
     99         for(i=0;i<k1;i++)
    100             ans+=w[y[i]][i];
    101 
    102         printf("%d\n",ans);
    103     }
    104 }
  • 相关阅读:
    编写安全代码:小心使用浮点数
    编写安全代码:有符号数和无符号数的移位区别右移
    封装了 C# 矩阵计算类CMarix
    几种位操作办法
    百度地图 鼠标绘制图形判 重叠 相交 demo
    eclipse 鼠标变成十字
    五(一)、spring 声明式事务注解配置
    eclipse创建Dynamic Web Project时忘记选中生成web.xml
    tomcat 请求地址去掉项目名称方法
    mybatis java类型和 jdbc类型 对应关系
  • 原文地址:https://www.cnblogs.com/zhsl/p/2777159.html
Copyright © 2011-2022 走看看