hdu 2255 奔小康赚大钱 最大权匹配KM

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255

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

题意描述:由于此题为中文题,这里不作翻译。

算法分析:最大权匹配问题,KM算法的入门题。百度KM算法有很多相关介绍的,这里不再累述。说明一点,KM优化:slack数组保存的是在dfs找增广路的时候随便求出Y集(二分图:X集和Y集)中不在相等子图中的每个y的值min(lx[x]-ly[y]-w[x][y]),最终算法复杂度为O(n^3)。

对编译知识不是很了解,为什么这道题G++提交TLE而C++提交AC,感觉很厉害很高级的样子。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cstdlib>
 5 #include<cmath>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 0x7fffffff
10 using namespace std;
11 const int maxn=300+10;
12
13 int n,nx,ny;
14 int lx[maxn],ly[maxn],visx[maxn],visy[maxn];
15 int link[maxn],slack[maxn];
16 int w[maxn][maxn];
17
18 int dfs(int x)
19 {
20     visx[x]=1;
21     for (int y=1 ;y<=ny ;y++)
22     {
23         if (visy[y]) continue;
24         int t=lx[x]+ly[y]-w[x][y];
25         if (t==0)
26         {
27             visy[y]=1;
28             if (link[y]==-1 || dfs(link[y]))
29             {
30                 link[y]=x;
31                 return 1;
32             }
33         }
34         else if (slack[y]>t) slack[y]=t;
35     }
36     return 0;
37 }
38
39 int KM()
40 {
41     memset(ly,0,sizeof(ly));
42     memset(link,-1,sizeof(link));
43     for (int x=1 ;x<=nx ;x++)
44     {
45         lx[x]=-inf;
46         for (int y=1 ;y<=ny ;y++)
47             lx[x]=max(lx[x],w[x][y]);
48     }
49     for (int x=1 ;x<=nx ;x++)
50     {
51         for (int j=1 ;j<=ny ;j++) slack[j]=inf;
52         while (1)
53         {
54             memset(visx,0,sizeof(visx));
55             memset(visy,0,sizeof(visy));
56             if (dfs(x)) break;
57             int d=inf;
58             for (int j=1 ;j<=ny ;j++)
59             {
60                 if (!visy[j] && slack[j]<d)
61                     d=slack[j];
62             }
63             for (int i=1 ;i<=nx ;i++)
64                 if (visx[i]) lx[i] -= d;
65             for (int i=1 ;i<=ny ;i++)
66             {
67                 if (visy[i]) ly[i] += d;
68                 else slack[i] -= d;
69             }
70         }
71     }
72     int ans=0;
73     for (int i=1 ;i<=ny ;i++)
74         if (link[i]!=-1) ans += w[link[i] ][i];
75     return ans;
76 }
77
78 int main()
79 {
80     while (scanf("%d",&n)!=EOF)
81     {
82         nx=ny=n;
83         for (int i=1 ;i<=n ;i++)
84         {
85             for (int j=1 ;j<=n ;j++)
86                 scanf("%d",&w[i][j]);
87         }
88         printf("%d\n",KM());
89     }
90     return 0;
91 }
时间: 2024-08-07 02:06:37

hdu 2255 奔小康赚大钱 最大权匹配KM的相关文章

HDU 2255 奔小康赚大钱(二分匹配之KM算法)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子. 另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓

hdu 2255 奔小康赚大钱(KM算法)

奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3248    Accepted Submission(s): 1413 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考

[ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)

奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间,刚好有n家老百姓,考虑到每家都要有房住(假设有老百姓没房子住的话.easy引起不安定因素),每家必须分配到一间房子且仅仅能得到一间房子. 还有一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.因为老百姓都比較富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比方有3间房

HDU 2255 ——奔小康赚大钱——————【KM算法裸题】

奔小康赚大钱 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 2255 Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到

HDU 2255 奔小康赚大钱 (KM算法 模板)

A - 奔小康赚大钱 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.

hdu 2255 奔小康赚大钱 (km算法模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2255 解题思路: 了解km算法以后,就可以直接套用km算法,km算法:完备匹配下的最大权匹配, 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #define maxn 310

HDU 2255 奔小康赚大钱 KM算法题解

KM算法求的是完备匹配下的最大权匹配,是Hungary算法的进一步,由于Hungary算法是最大匹配的算法,不带权. 经典算法,想不出来的了,要參考别人的.然后消化吸收吧. 由于真的非常复杂的算法. 我理解算法匹配思想: 1 開始的时候,全部边都记录自己的最优匹配,无论有没有冲突 2 递归循环的时候.假设找不到自己的最优匹配,那么就找次要匹配 3 次要匹配不行,继续找下一个次优匹配,全部点都一定要找到解 难点: 怎样记录这些信息,以便循环处理全部点. 牵涉到非常多什么增广路,交错树之类的,名词,

hdu 2255 奔小康赚大钱【最大权匹配】

题目链接:http://acm.acmcoder.com/showproblem.php?pid=2255 题意:中文 //KM算法模板题,用来测试一下模板 代码: #include <stdio.h> #include <ctime> #include <math.h> #include <limits.h> #include <complex> #include <string> #include <functional&g

hdu 2255奔小康赚大钱 KM算法模板

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹配的. 1.带权二分图:  在二分图中每一条边(x.y)相应一个权值Wi这样的二分图叫带权二分图. 一个匹配的权值就是该匹配中全部边的权值之和. 2,最优匹配: 权值最大的一个完美匹配.叫做最优匹配.       <km算法思想> 对于一个带权全然二分图:G(V.E),对于当中每一条边(x.y)边