POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了

先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配。

如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d。

这样两个点都在交替路中的时候x[i]+y[i]的和不边

X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配。

X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中。

题意:有n个人n个房子,每人进一个房子,求最少的总距离。

思路:对每条边取相反数,然后得到的结果再取相反数,就能得到最小权匹配。

#include<stdio.h>
#include<string.h>
#include<vector>
#include<algorithm>
#include<math.h>
#include<iostream>
#define INF 10000000
using namespace std;
char map[105][105];
struct point{
   int x,y;
}X[105],Y[105];
int W[105][105];
int macy[105];
bool check[105];
bool checkx[105];
int zx[105];
int zy[105];
int Y1[105];
int n;
bool dfs(int u)
{
    checkx[u]=1;
    for(int i=0;i<n;i++)
    {
        if(zx[u]+zy[i]==W[u][i]&&!check[i])
        {
            check[i]=1;
            if(macy[i]==-1||dfs(macy[i]))
            {
                macy[i]=u;
                return 1;
            }
        }
        if(!check[i])
        {
            Y1[i]=min(Y1[i],zx[u]+zy[i]-W[u][i]);
        }
    }
    return 0;
}
void gx()
{
    int a=INF;
    for(int i=0;i<n;i++)
        if(!check[i])
        a=min(a,Y1[i]);
    for(int i=0;i<n;i++)
    {
        if(check[i]) zy[i]+=a;
        if(checkx[i]) zx[i]-=a;
    }
}
void xyl()
{
    memset(macy,-1,sizeof(macy));
    for(int i=0;i<n;i++)
    {
        memset(check,0,sizeof(check));
        memset(checkx,0,sizeof(checkx));
        if(!dfs(i))
        {
            i--;
            gx();
        }
    }
}
int main()
{
    int N,M;
    while(scanf("%d%d",&N,&M)!=EOF)
    {
        if(N==0&&M==0) return 0;
        for(int i=0;i<N;i++)
            scanf("%s",map[i]);
            int r1=0,r2=0;
        for(int i=0;i<N;i++)
            for(int j=0;j<M;j++)
        {
            if(map[i][j]==‘H‘)
            {
                X[r1].x=i;
                X[r1].y=j;
                r1++;
            }
            else if(map[i][j]==‘m‘)
            {
                Y[r2].x=i;
                Y[r2].y=j;
                r2++;
            }
        }
        memset(zy,0,sizeof(zy));
        for(int i=0;i<r1;i++)
       {
           zx[i]=-INF;
           for(int j=0;j<r2;j++)
            {
                W[i][j]=abs(X[i].x-Y[j].x)+abs(X[i].y-Y[j].y);
                W[i][j]*=-1;
                zx[i]=max(zx[i],W[i][j]);
                Y1[j]=INF;
            }
       }
        n=r1;
        //return 0;
        xyl();
        int p=0;
        for(int i=0;i<n;i++)
        {
            int u=macy[i];
            p+=W[u][i];
        }
        printf("%d\n",-p);
    }
}

POJ 2195 二分图最小权匹配KM算法

时间: 2024-07-31 15:45:17

POJ 2195 二分图最小权匹配KM算法的相关文章

poj 2195 Going Home 二分图最小权匹配KM算法

题意: 有n个人要回到n间房子里,每间房子只允许一个人,求n个人要走的最小距离和. 分析: 裸的二分图最小权匹配,KM搞之. 代码: //poj 2195 //sep9 #include <iostream> using namespace std; const int maxN=128; char g[maxN][maxN]; int mx[maxN],my[maxN],hx[maxN],hy[maxN]; int w[maxN][maxN]; int lx[maxN],ly[maxN],l

【POJ 2195】 Going Home(KM算法求最小权匹配)

[POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 20303   Accepted: 10297 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit ste

[ACM] POJ 3686 The Windy&#39;s (二分图最小权匹配,KM算法,特殊建图)

The Windy's Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 4158   Accepted: 1777 Description The Windy's is a world famous toy factory that owns M top-class workshop to make toys. This year the manager receivesN orders for toys. The man

poj 3686 The Windy&#39;s 二分图最小权和匹配KM

题意: 给n个玩具和m家工厂,每个玩具只能在一家工厂加工,给出每个玩具在每家工厂需要的加工时间,求这n个玩具完成时间平均值的最小值. 分析: 求最小和容易联系到二分图的最小权和匹配,这题的问题是n与m的大小关系是不确定的,也是就是说可能会有多个玩具到同一家工厂里加工的情况,这似乎与匹配的定义相矛盾.但仔细一想,如果多个玩具在同一工厂加工,他们的完成时间肯定是不一样的,所以讲w[i][j]=z 拆成w[i][0*m+j]=z,w[i][1*m+j]=2*z,w[i][2*m+j]=3*z.....

[ACM] HDU 1533 Going Home (二分图最小权匹配,KM算法)

Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2963    Accepted Submission(s): 1492 Problem Description On a grid map there are n little men and n houses. In each unit time, every

二分图 最大权匹配 km算法

这个算法的本质还是不断的找增广路: KM算法的正确性基于以下定理:若由二分图中所有满足A[i]+B[j]=w[i,j]的边(i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配. 这个定理是显然的.因为对于二分图的任意一个匹配,如果它包含于相等子图,那么它的边权和等于所有顶点的顶标和:如果它有的边不包含于相等子图,那么它的边权和小于所有顶点的顶标和.所以相等子图的完备匹配一定是二分图的最大权匹配. (1)可行点标:每个点有一个标号,记lx[i]为X方点i的标号,l

poj 2195 二分图带权匹配

题意:有一个矩阵,某些格有人,某些格有房子,每个人可以上下左右移动,问给每个人进一个房子,所有人需要走的距离之和最小是多少. 貌似以前见过很多这样类似的题,都不会,现在知道是用KM算法做了 KM算法目前还没弄懂,先套模板做 Sample Input 2 2 .m H. 5 5 HH..m ..... ..... ..... mm..H 7 8 ...H.... ...H.... ...H.... mmmHmmmm ...H.... ...H.... ...H.... 0 0 Sample Out

HDU 3722 Card Game(二分图最佳完美匹配+KM算法)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=3722 1 /* 2 问题 3 将任意的两个字符串进行匹配,使得匹配后权值和最大 4 5 解题思路 6 将任意的字符串的权值计算出来,使用KM算法即可. 7 */ 8 #include<cstdio> 9 #include<cstring> 10 #include<algorithm> 11 using namespace std; 12 13 const int maxn

二分图最大权匹配(KM算法)

#80. 二分图最大权匹配 统计 描述 提交 自定义测试 从前一个和谐的班级,有 $n_l$ 个是男生,有 $n_r$ 个是女生.编号分别为 $1, \dots, n_l$ 和 $1, \dots, n_r$. 有若干个这样的条件:第 $v$ 个男生和第 $u$ 个女生愿意结为配偶,且结为配偶后幸福程度为 $w$. 请问这个班级里幸福程度之和最大是多少? 输入格式 第一行三个正整数,$n_l, n_r, m$. 接下来 $m$ 行,每行三个整数 $v, u, w$ 表示第 $v$ 个男生和第 $