HDU 1533 二分图最小权匹配 Going Home

带权二分图匹配,把距离当做权值,因为是最小匹配,所以把距离的相反数当做权值求最大匹配。

最后再把答案取一下反即可。

  1 #include <iostream>
  2 #include <cstdio>
  3 #include <cstring>
  4 #include <algorithm>
  5 #include <map>
  6 #include <vector>
  7 #include <cmath>
  8 #define MP make_pair
  9 using namespace std;
 10
 11 typedef pair<int, int> PII;
 12
 13 const int maxn = 100 + 10;
 14
 15 int n;
 16 PII house[maxn], men[maxn];
 17 char grid[maxn][maxn];
 18
 19 int row, col;
 20
 21 int dist(const PII& a, const PII& b)
 22 { return abs(a.first - b.first) + abs(a.second - b.second); }
 23
 24 //KM algorithm
 25 int W[maxn][maxn];
 26 int Lx[maxn], Ly[maxn];
 27 int lft[maxn];
 28 bool S[maxn], T[maxn];
 29
 30 bool match(int u)
 31 {
 32     S[u] = true;
 33     for(int v = 1; v <= n; v++)
 34         if(Lx[u] + Ly[v] == W[u][v] && !T[v])
 35         {
 36             T[v] = true;
 37             if(!lft[v] || match(lft[v]))
 38             {
 39                 lft[v] = u;
 40                 return true;
 41             }
 42         }
 43     return false;
 44 }
 45
 46 void update()
 47 {
 48     int a = 100000000;
 49     for(int u = 1; u <= n; u++) if(S[u])
 50         for(int v = 1; v <= n; v++) if(!T[v])
 51             a = min(a, Lx[u] + Ly[v] - W[u][v]);
 52     for(int u = 1; u <= n; u++)
 53     {
 54          if(S[u]) Lx[u] -= a;
 55          if(T[u]) Ly[u] += a;
 56     }
 57 }
 58
 59 void KM()
 60 {
 61     for(int i = 1; i <= n; i++)
 62     {
 63         Lx[i] = *max_element(W[i]+1, W[i]+1+n);
 64         Ly[i] = 0;
 65         lft[i] = 0;
 66     }
 67     for(int u = 1; u <= n; u++)
 68     {
 69         for(;;)
 70         {
 71             memset(S, false, sizeof(S));
 72             memset(T, false, sizeof(T));
 73             if(match(u)) break;
 74             else update();
 75         }
 76     }
 77 }
 78
 79 int main()
 80 {
 81     while(scanf("%d%d", &row, &col) == 2 && row)
 82     {
 83         n = 0;
 84
 85         for(int i = 0; i < row; i++) scanf("%s", grid[i]);
 86         int hcnt = 0, mcnt = 0;
 87         for(int i = 0; i < row; i++)
 88             for(int j = 0; j < col; j++)
 89             {
 90                 if(grid[i][j] == ‘H‘)
 91                     house[++hcnt] = MP(i, j);
 92                 else if(grid[i][j] == ‘m‘)
 93                     men[++mcnt] = MP(i, j);
 94             }
 95
 96         //build graph
 97         n = hcnt;
 98         for(int i = 1; i <= n; i++)
 99             for(int j = 1; j <= n; j++)
100                 W[i][j] = -dist(men[i], house[j]);
101
102         KM();
103
104         int ans = 0;
105         for(int i = 1; i <= n; i++) ans += W[lft[i]][i];
106         printf("%d\n", -ans);
107     }
108
109     return 0;
110 }

代码君

时间: 2024-10-11 12:23:53

HDU 1533 二分图最小权匹配 Going Home的相关文章

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 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

[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

Cyclic Tour (hdu 1853 二分图最小权问题)

Cyclic Tour Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/65535 K (Java/Others) Total Submission(s): 1883    Accepted Submission(s): 941 Problem Description There are N cities in our country, and M one-way roads connecting them. Now L

[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

二分图最佳匹配,求最大权匹配或最小权匹配

Beloved Sons http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1338 题意:国王有N个儿子,现在每个儿子结婚都能够获得一定的喜悦值,王子编号为1-N,有N个女孩的编号同样为1-N,每个王子心中都有心仪的女孩,现在问如果安排,能够使得题中给定的式子和最大. 分析:其实题目中那个开根号是个烟雾弹,只要关心喜悦值的平方即可.那么对王子和女孩之间构边,边权为喜悦值的平方,对于每一个王子虚拟出一个女孩边权为0,这样是为了所

UVa 1349 (二分图最小权完美匹配) Optimal Bus Route Design

题意: 给出一个有向带权图,找到若干个圈,使得每个点恰好属于一个圈.而且这些圈所有边的权值之和最小. 分析: 每个点恰好属于一个有向圈 就等价于 每个点都有唯一后继. 所以把每个点i拆成两个点,Xi 和 Yi ,然后求二分图最小权完美匹配(流量为n也就是满载时,就是完美匹配). 1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 200 + 10; 6 const int INF = 10000000

hdu 2255 二分图最大权匹配 *

题意:说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另 一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格, 比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出2

poj3565Ants【最小权匹配】

大意: 左图为一个坐标轴上的点  其中黑点代表ants 白点代表apple 问怎样安排ants匹配apple才能使人一两条边不想交 分析: 如左图,我们假设a->d,b->c为一个最佳匹配  交点为e 那么ad+bc = ae+ ed + be + ec = (ae + ec) + (be + ed)  该值大于ac+bd 所以匹配为最佳匹配不成立 因此我们只要求出二分图的最小匹配就是结果了 但是wa了: wa的代码: 1 #include <iostream> 2 #includ