HDU 2426 Interesting Housing Problem(EK模板)
来源:互联网 发布:个人域名申请 编辑:程序博客网 时间:2024/05/22 12:22
题目地址
题意:有n个学生和m个宿舍,每个宿舍只能一个人住,然后接下来的E行有a,b,c三个数,代表的是学生a对宿舍b的满意度为c,假如满意度小于0则不会入住该宿舍,如果没有写出满意度则代表的是不会入住该宿舍。求所有学生能不能入住成功,最大的满意度为多少?
思路:如果最后满意的宿舍比n小则说明了不可能成功入住,所有直接输出-1,否则进行带权二分图最佳匹配EK算法就好了,模板题
#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 1000#define M 500010#define LL __int64#define inf 0x3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1e9 + 7;int mapp[N][N];//表明好感度bool usem[N];struct Kuhn_Munkras { int nx, ny; int linker[N];//每个y所对应的x int lx[N];//x的期望值 int ly[N];//y的期望值 int slack[N];//每个y能被x匹配的最小还需的期望值 bool visx[N], visy[N];//匹配过的标记 void init(int n, int m) { this->nx = n; this->ny = m; memset(linker, -1, sizeof(linker));//每个y最初都没有匹配 memset(ly, 0, sizeof(ly));//最初每个y的期望值都是0 } bool dfs(int x) { visx[x] = true; for (int y = 1; y <= ny; y++) { if (!visy[y]) { int tmp = lx[x] + ly[y] - mapp[x][y]; if (tmp == 0) {//如果两边的期望值相加等于好感度则符合要求 visy[y] = true; if (linker[y] == -1 || dfs(linker[y])) {//没有被匹配过的y,或者能换匹配的y linker[y] = x; return true; } } else if (slack[y]>tmp) { slack[y] = tmp; //可以理解为该y要得到x的匹配,还需多少期望值,取最小值 } } } return false; } int solve(int n, int m) { init(n, m); for (int i = 1; i <= nx; i++) { lx[i] = -inf; for (int j = 1; j <= ny; j++) { if (mapp[i][j]>lx[i]) { lx[i] = mapp[i][j];//取最大的好感度为x的期望值 } } } for (int x = 1; x <= nx; x++) {//尝试为每一个x解决匹配问题 memset(slack, inf, sizeof(slack)); while (true) {//找不到就降低期望值 memset(visx, false, sizeof(visx)); memset(visy, false, sizeof(visy)); if (dfs(x)) {//找到就离开 break; } int d = inf; for (int i = 1; i <= ny; i++) { if (!visy[i] && d>slack[i]) {//找到最小的差值 d = slack[i]; } } for (int i = 1; i <= nx; i++) {//对所有访问过的x减小期望值 if (visx[i]) { lx[i] -= d; } } for (int i = 1; i <= ny; i++) {//对所有访问过的y增加期望值 if (visy[i]) { ly[i] += d; } else { slack[i] -= d; } } } } int res = 0; for (int i = 1; i <= ny; i++) { if (linker[i] != -1) {//匹配成功的求和 res += mapp[linker[i]][i]; } } return res; }}KM;int main() { int n, m, E; int a, b, c; int Case = 1; cin.sync_with_stdio(false); while (cin >> n >> m >> E) { memset(mapp, -inf, sizeof(mapp)); memset(usem, false, sizeof(usem)); for (int i = 0; i < E; i++) { cin >> a >> b >> c; a++, b++; if (c >= 0) mapp[a][b] = c, usem[b] = true; } a = 0; for (int i = 1; i <= m; i++) { if (usem[i]) a++; } if (a < n) { cout << "Case " << Case++ << ": -1" << endl; continue; } cout << "Case " << Case++ << ": " << KM.solve(n, m) << endl; } return 0;}
阅读全文
0 0
- HDU 2426 Interesting Housing Problem(EK模板)
- HDU 2426 Interesting Housing Problem
- HDU-2426 Interesting Housing Problem
- hdu 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem
- HDU 2426 Interesting Housing Problem 二分匹配(KM模板)或者最小费用最大流
- hdu 2426 Interesting Housing Problem(最大权值匹配)
- HDU 2426 Interesting Housing Problem(KM完美匹配)
- hdu 2426 Interesting Housing Problem (KM)
- hdu 2426 Interesting Housing Problem (KM算法)
- hdu 2426 Interesting Housing Problem(KM)
- hdu 2426 Interesting Housing Problem【KM】
- Interesting Housing Problem hdu 2426 KM模板 +二分图最佳匹配
- HDU 2426 Interesting Housing Problem(二分图最优匹配)
- hdu 2426 Interesting Housing Problem 最大权值 && KM算法
- HDU 2426 Interesting Housing Problem(二分图最优匹配)
- hdoj--2426--Interesting Housing Problem(最大费用流)
- 使用ViewPager实现顶部tabbar切换界面
- 中电投-镇宁3号集合资产管理计划
- Android之bitmap的使用
- 一、storm基础概念
- 节点操作
- HDU 2426 Interesting Housing Problem(EK模板)
- Bootstrap学习笔记——Bootstrap的基本介绍
- webmagic 爬取示例,新手学习
- 前端面试准备(1)
- Java实现邮件发送(带附件)
- 欢迎使用CSDN-markdown编辑器
- 轻装上阵Html5游戏开发,JEESJS(二)
- 自动代码生成的Java Code Template
- Tomcat运行时,发生磁盘空间不足,无法处理此命令