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

http://acm.hdu.edu.cn/showproblem.php?pid=2426

题意:
每n个学生和m个房间,现在要为每个学生安排一个房间居住,每个学生对于一些房间有一些满意度,如果满意度为负就说明该学生不喜欢住在这房间。现在问如何安排可以使所有学生的满意度总和最大。(不能将学生安排到他不喜欢的房间或者他没有评价的房间)

思路:

二分图的最佳匹配,注意题目的要求即可。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 using namespace std;
  5 const int maxn = 500+5;
  6 const int INF = 0x3f3f3f3f;
  7
  8 int n, m, k;
  9 int g[maxn][maxn];
 10 int lx[maxn], ly[maxn];
 11 bool S[maxn], T[maxn];  //记录左右两边节点是否已匹配
 12 int match[maxn];
 13 int slack[maxn];   //差值
 14
 15 bool dfs(int i)
 16 {
 17     S[i] = true;
 18     for (int j = 1; j <= m; ++j)
 19     {
 20         if (T[j]) continue;   //每一轮匹配,右边节点只能一次
 21         int gap = lx[i] + ly[j] - g[i][j];
 22         if (gap == 0)   //如果符合要求
 23         {
 24             T[j] = true;
 25             if (match[j] == -1 || dfs( match[j] ))
 26             {
 27                 match[j] = i;
 28                 return true;
 29             }
 30         }
 31         else slack[j] = min(slack[j], gap);
 32     }
 33     return false;
 34 }
 35
 36 int KM()
 37 {
 38     memset(match, -1, sizeof match);
 39     memset(ly, 0, sizeof ly);   //初始化ly为0
 40     for (int i = 1; i<=n; i++)  //初始化lx[i]为该节点所有边中的最大权值
 41     {
 42         lx[i] = g[i][1];
 43         for (int j = 2; j<=m; j++)
 44             lx[i] = max(lx[i], g[i][j]);
 45     }
 46     for (int i=1; i<=n; i++)    //尝试为每个节点匹配节点
 47     {
 48         memset(slack,INF,sizeof(slack));    //因为要取最小值,初始化为无穷大
 49         while (true) {
 50             memset(S, false, sizeof S);   //记录每轮匹配中左右节点是否被尝试匹配过
 51             memset(T, false, sizeof T);
 52             if (dfs(i)) break;
 53             int d = INF;
 54             for (int j=1; j<=m; j++)
 55                 if (!T[j]) d = min(d, slack[j]);
 56             for (int j=1; j<=n; ++j)
 57                 if (S[j]) lx[j] -= d;
 58             for(int j=1;j<=m;j++)
 59             {
 60                 if (T[j]) ly[j] += d;
 61                 else slack[j] -= d;
 62             }
 63         }
 64     }
 65
 66     int result = 0,flag=0;
 67     for(int i = 1; i <=m; i++){
 68         if(match[i]==-1||g[match[i]][i]==-INF)
 69             continue;
 70       if(match[i]>-1){
 71         result += g[match[i]][i];
 72         flag++;
 73       }
 74     }
 75     if(flag<n) result=-1;
 76     return result;
 77
 78 }
 79
 80 int main()
 81 {
 82     //freopen("in.txt","r",stdin);
 83     int cas = 0;
 84     while(~scanf("%d%d%d",&n,&m,&k))
 85     {
 86         if(n>m)
 87         {
 88             printf("Case %d: %d\n", ++cas, -1);
 89             continue;
 90         }
 91         for(int i=1;i<=n;i++)
 92         for(int j=1;j<=m;j++)
 93             g[i][j] = -INF;
 94         for(int i=0;i<k;i++)
 95         {
 96             int u,v,w;
 97             scanf("%d%d%d",&u,&v,&w);
 98             u++; v++;
 99             if(w>=0) g[u][v] = w;
100         }
101         int ans = KM();
102         printf("Case %d: %d\n", ++cas, ans);
103     }
104     return 0;
105 }

原文地址:https://www.cnblogs.com/zyb993963526/p/9291038.html

时间: 2024-10-31 23:23:47

HDU 2426 Interesting Housing Problem(二分图最佳匹配)的相关文章

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

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 (最大权完美匹配)【KM】

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

HDU2426 Interesting Housing Problem(KM匹配 )

题意:N个学生安排到M个宿舍,每个学生对宿舍有个评价,正数,0,负数,现在评价是负数的,不能让这个学生去这个房间,问怎么安排让所有的学生都住进宿舍且评价最大. 思路:建立图的权重时,筛选掉负数边. #include<cstdio> #include<iostream> #include<algorithm> #include<cmath> #include<set> #include<map> #include<string&g

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

HDU2255 奔小康赚大钱【二分图最佳匹配】

题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=2255 题目大意: 村里要分房子. 有N家老百姓,刚好有N间房子.考虑到每家都要有房住,每家必须分配到一间房子且 仅仅能分配到一间房子.另外, 村长为了得到最大利益,让老百姓对房子进行估价. 比方有3件房子,一 家老百姓能够对第一间出10万,对第二间出2万,对第三间出4万.第二家老百姓能够对第一间出8万, 对第二家出3万,对第三间出5万.那么问题来了:怎么分配,才干使利益最大化. (村民房子不一定

POJ2195 Going Home【二分图最佳匹配】

题目链接: http://poj.org/problem?id=2195 题目大意: 在一个N*M的矩阵中,有M个人和M个房子,每个人要安排一个房子,每个房子只能安排一个人. 而每个人移动一步需要一美元.那么问题来了:求为每个人安排房子移动所需要的金钱最小值是多 少. 思路: 做一个二分图,一边为人,另一边为房子,如果把人和房子之间的距离作为边权的话,问题就变成 了求带权二分图最小权和的最佳匹配.这里我们为了方便计算,吧人和房子之间的距离的负值作为 边权,那么就变成了求带权二分图最大权和的最佳匹

二分图最佳匹配

1 /* 2 * this code is made by bjfu_song 3 * Problem: 1227 4 * Verdict: Accepted 5 * Submission Date: 2014-10-05 14:53:22 6 * Time: 132MS 7 * Memory: 2340KB 8 */ 9 #include<iostream> 10 #include<stdio.h> 11 #include<string.h> 12 #include&