hdu 2426 Interesting Housing Problem 最大权匹配KM算法

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

For any school, it is hard to find a feasible accommodation plan with every student assigned to a suitable apartment while keeping everyone happy, let alone an optimal one. Recently the president of University ABC, Peterson, is facing a similar problem. While Peterson does not like the idea of delegating the task directly to the class advisors as so many other schools are doing, he still wants to design a creative plan such that no student is assigned to a room he/she dislikes, and the overall quality of the plan should be maximized. Nevertheless, Peterson does not know how this task could be accomplished, so he asks you to solve this so-called "interesting" problem for him.
Suppose that there are N students and M rooms. Each student
is asked to rate some rooms (not necessarily all M rooms) by stating how he/she
likes the room. The rating can be represented as an integer, positive value
meaning that the student consider the room to be of good quality, zero
indicating neutral, or negative implying that the student does not like living
in the room. Note that you can never assign a student to a room which he/she has
not rated, as the absence of rating indicates that the student cannot live in
the room for other reasons.
With limited information available, you‘ve
decided to simply find an assignment such that every student is assigned to a
room he/she has rated, no two students are assigned to the same room, and the
sum of rating is maximized while satisfying Peterson‘s requirement. The question
is … what exactly is the answer?

题意描述:学校里有n个学生和m个公寓房间,每个学生对一些房间有一些打分,如果分数为正,说明学生喜欢这个房间,若为0,对这个房间保持中立,若为负,则不喜欢这个房间。学生不会住进不喜欢的房间和没有打分的房间。问安排这n个学生来求最大的分数。

算法分析:KM算法。n个学生作为X集,m个房间作为Y集,然后调用KM算法就可以了。

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

hdu 2426 Interesting Housing Problem 最大权匹配KM算法的相关文章

HDU 2426 Interesting Housing Problem (最大权完美匹配)【KM】

<题目链接> 题目大意: 学校里有n个学生和m个公寓房间,每个学生对一些房间有一些打分,如果分数为正,说明学生喜欢这个房间,若为0,对这个房间保持中立,若为负,则不喜欢这个房间.学生不会住进不喜欢的房间和没有打分的房间.问安排这n个学生来求最大的分数,如果不能够使这些学生全部入住房间,就输出-1,每个房间最多只能住一个学生. 解题分析: 因为需要求带权二分图,所以用KM算法,需要注意的是,边权为负的两点不能进行匹配,并且,最后需要判断是否符合题意,即是否所有学生都有房间. 1 #include

HDU 2426 Interesting Housing Problem(KM完美匹配)

HDU 2426 Interesting Housing Problem 题目链接 题意:n个学生,m个房间,给定一些学生想住房的喜欢度,找一个最优方案使得每个学生分配一个房间,并且使得喜欢度最大,注意这题有个坑,就是学生不会住喜欢度为负的房间 思路:很明显的KM最大匹配问题,喜欢度为负直接不连边即可 代码: #include <cstdio> #include <cstring> #include <cmath> #include <algorithm>

hdu 2426 Interesting Housing Problem (KM算法)

Interesting Housing Problem Time Limit: 10000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2388    Accepted Submission(s): 879 Problem Description For any school, it is hard to find a feasible accommodation

HDU 2426 Interesting Housing Problem(二分图最佳匹配)

http://acm.hdu.edu.cn/showproblem.php?pid=2426 题意:每n个学生和m个房间,现在要为每个学生安排一个房间居住,每个学生对于一些房间有一些满意度,如果满意度为负就说明该学生不喜欢住在这房间.现在问如何安排可以使所有学生的满意度总和最大.(不能将学生安排到他不喜欢的房间或者他没有评价的房间) 思路: 二分图的最佳匹配,注意题目的要求即可. 1 #include<iostream> 2 #include<cstdio> 3 #include&

带权二分图的最大权匹配 KM算法模版

带权二分图的最大权匹配 KM算法模版 下面是kuangbin大神的模版,已通过西电oj1048的测试 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set

二分图 最大权匹配 km算法

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

二分图最大权匹配(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$ 个男生和第 $

HDU3488 Tour —— 二分图最大权匹配 KM算法

题目链接:https://vjudge.net/problem/HDU-3488 Tour Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)Total Submission(s): 3720    Accepted Submission(s): 1777 Problem Description In the kingdom of Henryy, there are N (2 <=

Interesting Housing Problem HDU - 2426 (KM)

Interesting Housing Problem HDU - 2426 题意:n个人,m个房间,安排住宿.要求每个人不能分到不喜欢的房间,且使满意度最大. 不用slack几乎要超时~ 1 #include <bits/stdc++.h> 2 using namespace std; 3 const int inf=0x3f3f3f3f; 4 const int maxn=550; 5 6 int c[maxn][maxn]; 7 int vb[maxn],vg[maxn],eb[maxn