HDU 2426 Interesting Housing Problem 二分匹配(KM模板)或者最小费用最大流
来源:互联网 发布:职称论文比较软件 编辑:程序博客网 时间:2024/05/17 05:00
点击打开链接
Interesting Housing Problem
Time Limit: 10000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2151 Accepted Submission(s): 798
Problem Description
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?
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?
Input
There are multiple test cases in the input file. Each test case begins with three integers, N, M, and E (1 <= N <= 500, 0 <= M <= 500, 0 <= E <= min(N * M, 50000)), followed by E lines, each line containing three numbers, Si, Ri, Vi, (0 <= Si < N, 0 <= Ri < M, |Vi| <= 10000), describing the rating Vi given by student Si for room Ri. It is guaranteed that each student will rate each room at most once.
Each case is followed by one blank line. Input ends with End-of-File.
Each case is followed by one blank line. Input ends with End-of-File.
Output
For each test case, please output one integer, the requested value, on a single line, or -1 if no solution could be found. Use the format as indicated in the sample output.
Sample Input
3 5 50 1 50 2 71 1 61 2 32 4 51 1 10 0 01 1 0
Sample Output
Case 1: 18Case 2: 0Case 3: -1
Source
2008 Asia Hangzhou Regional Contest Online
Recommend
lcy
题意:一个学校里面有n个学生,m个宿舍,学生对某一宿舍有一个r值,代表该学生对该宿舍的满意度,r>0说明满意,r=0,说明不喜欢也不讨厌,r<0,说明讨厌。每个宿舍只住一个学生,校长应该怎么分配学生才能使得满意度达到最大?
用二分匹配来做比较简单,直接套KM模板就行。如果最小费用最大流的话,关键在于建图,建一个超级源点与学生相连,超级汇点与宿舍相连,学生和宿舍之间也有联系。但是,我用最小费用最大流来做此题,结果是TLE,可能有些地方没有优化好,不过,我知道,用最小费用最大流的思想是可以AC此题的。
//二分匹配#include<stdio.h>#include<string.h>#define inf 99999using namespace std;int g[507][507];int lx[507],ly[507];int slack[507],match[507];bool visx[507],visy[507];int n,m,t;bool dfs(int cur){ visx[cur]=true; for(int y=1;y<=m;y++) { if(visy[y])continue; int t=lx[cur]+ly[y]-g[cur][y]; if(t==0) { visy[y]=true; if(match[y]==-1||dfs(match[y])) { match[y]=cur; return true; } } else if(slack[y]>t) { slack[y]=t; } } return false;}int KM(){ memset(match,-1,sizeof(match)); memset(ly,0,sizeof(ly)); for(int i=1;i<=n;i++) { lx[i]=-inf; for(int j=1;j<=m;j++) { if(g[i][j]>lx[i]) lx[i]=g[i][j]; } } for(int x=1;x<=n;x++) { for(int i=1;i<=m;i++) slack[i]=inf; while(true) { memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(dfs(x))break; int d=inf; for(int i=1;i<=m;i++) { if(!visy[i]&&d>slack[i]) d=slack[i]; } for(int i=1;i<=n;i++) if(visx[i]) { lx[i]-=d; } for(int i=1;i<=m;i++) if(visy[i])ly[i]+=d; else slack[i]-=d; } } int reslut=0,flag=0; for(int i=1;i<=m;i++) { if(match[i]==-1||g[match[i]][i]==-inf) continue; if(match[i]>-1) { reslut+=g[match[i]][i]; flag++; } } if(flag<n)reslut=-1; return reslut;}int main(){ int cas=1; while(scanf("%d%d%d",&n,&m,&t)!=EOF) { memset(g,0,sizeof(g)); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) g[i][j]=-inf; int a,b,c; for(int i=1;i<=t;i++) { scanf("%d%d%d",&a,&b,&c); a++;b++; if(c<0)continue; g[a][b]=c; } int ans=KM(); printf("Case %d: %d\n",cas++,ans); } return 0;}
//TLE的最小费用最大流#include <iostream>#include <algorithm>#include <string>#include <stdio.h>#include <string.h>#include <stdlib.h>#include <memory.h>#include <queue>#include <vector>#include <cmath>using namespace std;int sumFlow;const int MAXN = 507;const int INF = 1000000000;struct Edge{ int u, v, cap, cost; int next;} edge[250000];int NE,N,M,E;int head[MAXN], dist[MAXN], pp[MAXN];bool vis[MAXN];void init(){ NE = 0; memset(head, -1, sizeof(head));}void addedge(int u, int v, int cap, int cost){ edge[NE].u = u; edge[NE].v = v; edge[NE].cap = cap; edge[NE].cost = cost; edge[NE].next = head[u]; head[u] = NE++; edge[NE].u = v; edge[NE].v = u; edge[NE].cap = 0; edge[NE].cost = -cost; edge[NE].next = head[v]; head[v] = NE++;}bool SPFA(int s, int t, int n){ int i, u, v; queue <int> qu; memset(vis,false,sizeof(vis)); memset(pp,-1,sizeof(pp)); for(i = 0; i <= n; i++) dist[i] = INF; vis[s] = true; dist[s] = 0; qu.push(s); while(!qu.empty()) { u = qu.front(); qu.pop(); vis[u] = false; for(i = head[u]; i != -1; i = edge[i].next) { v = edge[i].v; if(edge[i].cap && dist[v] > dist[u] + edge[i].cost) { dist[v] = dist[u] + edge[i].cost; pp[v] = i; if(!vis[v]) { qu.push(v); vis[v] = true; } } } } if(dist[t] == INF) return false; return true;}int MCMF(int s, int t, int n) // minCostMaxFlow{ int flow = 0; // 总流量 int i, minflow, mincost; mincost = 0; while(SPFA(s, t, n)) { minflow = INF + 1; for(i = pp[t]; i != -1; i = pp[edge[i].u]) if(edge[i].cap < minflow) minflow = edge[i].cap; flow += minflow; for(i = pp[t]; i != -1; i = pp[edge[i].u]) { edge[i].cap -= minflow; edge[i^1].cap += minflow; } mincost += dist[t] * minflow; } sumFlow = flow; // 最大流 if(sumFlow!=N) return 1; return mincost;}int main(){ int cas=1; while(scanf("%d%d%d",&N,&M,&E)!=EOF) { int u, v, c; int s,r,vv; init(); int S=0;//S是源点 int T=N+M+1;//T是汇点 for(int i=0;i<E;i++) { scanf("%d%d%d",&s,&r,&vv); s++,r++; if(v>=0) { addedge(s,N+r,1,-vv); } } for(int i=1;i<=N;i++) { addedge(0,i,1,0); } for(int i=1;i<=M;i++) addedge(N+i,T,1,0); int ans =- MCMF(S, T, T+1);//T+1是点的个数 printf("Case %d: %d\n", cas++,ans); } return 0;}
- HDU 2426 Interesting Housing Problem 二分匹配(KM模板)或者最小费用最大流
- HDU 2426 Interesting Housing Problem 最小费用最大流 or KM算法
- Interesting Housing Problem hdu 2426 KM模板 +二分图最佳匹配
- HDU 2426 Interesting Housing Problem(KM完美匹配)
- hdoj--2426--Interesting Housing Problem(最大费用流)
- HDU2426 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】
- HDU 1533Going Home(KM算法求二分图最小权匹配或者最小费用最大流)
- POJ 2426 Interesting Housing Problem (最大费用最大流)
- HDU 2426 Interesting Housing Problem(二分图最优匹配)
- HDU 2426 Interesting Housing Problem(二分图最优匹配)
- HDU 2426 Interesting Housing Problem【最大费用最大流 && 常规题】
- hdoj 2246 Interesting Housing Problem 【最大费用最大流 or KM算法】
- HDU 1533 Going Home 最小费用最大流(入门)(模板)或者 二分匹配
- hdu 2426 Interesting Housing Problem(最大权值匹配)
- WCF 共享端口步骤
- windows server 2008 远程桌面IP绊定设置
- 删除一个指针之后要置为NULL
- 如何用纯CSS固定thead实现表格滚动?tbody设置overflow之密
- c#如何实现在两个窗体(Form)间传输数据或变量
- HDU 2426 Interesting Housing Problem 二分匹配(KM模板)或者最小费用最大流
- MAC配置python环境和一些库的心得,过程简略,只写大概步骤
- UVa 11111 - Generalized Matrioshkas
- 单播、广播、组播
- spring+quartz 完整例子
- C语言_文件的操作
- 泛型方法
- ext4.x grid 相关知识备忘
- oracle基础学习