Interesting Housing Problem
Time Limit: 10000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2876 Accepted Submission(s): 1025
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, S
i, R
i, V
i, (0 <= S
i < N, 0 <= R
i < M, |V
i| <= 10000), describing the rating V
i given by student S
ifor room R
i. 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 5 0 1 5 0 2 7 1 1 6 1 2 3 2 4 5 1 1 1 0 0 0 1 1 0
Sample Output
Case 1: 18 Case 2: 0Case 3: -1
题意:有n个学生m个房间,学生对房间有评价(不一定评价所有的房间),正数代表喜欢,0代表中立,负数代表不喜欢,把所有的学生分配一个房间,不能把学生分配给他不喜欢的房间,也不能分配给他未评价的房间,求评价的最大和,不能满足要求输出-1
//先把处理一下学生和房间的关系,评分为负不能加边,同时统计评分为非负的房间数,如果小于n,不能进行完备匹配,则不能满足要求,直接输出-1,满足的话则进行套KM算法,最后再判断是否有完备匹配,有则输出最大值,否则-1 #include<iostream> #include<algorithm> #include<cstdio> #include<queue> #include<map> #include<vector> #include<cstring> #include<cmath> using namespace std; const int N = 510; const int INF = 0x3f3f3f3f; int lx[N], ly[N], match[N], slack[N], s[N][N]; int nx, ny; bool visx[N], visy[N]; bool hungary(int v) { visx[v] = true; for(int i = 0; i < ny; i++) { if(visy[i]) continue; if(lx[v] + ly[i] == s[v][i]) { visy[i] = true; if(match[i] == -1 || hungary(match[i])) { match[i] = v; return true; } } else slack[i] = min(slack[i], lx[v] + ly[i] - s[v][i]); } return false; } void km() { memset(ly, 0, sizeof ly); for(int i = 0; i < nx; i++) lx[i] = -INF; for(int i = 0; i < nx; i++) for(int j = 0; j < ny; j++) lx[i] = max(lx[i], s[i][j]); for(int i = 0; i < nx; i++) { memset(slack, 0x3f, sizeof slack); while(true) { memset(visx, 0, sizeof visx); memset(visy, 0, sizeof visy); if(hungary(i)) break; else { int tmp = INF; for(int j = 0; j < ny; j++) if(!visy[j]) tmp = min(tmp, slack[j]); for(int j = 0; j < nx; j++) if(visx[j]) lx[j] -= tmp; for(int j = 0; j < ny; j++) if(visy[j]) ly[j] += tmp; else slack[j] -= tmp; } } } } int main() { int n, m, k, x = 0; int a, b, c; bool used[N]; while(~ scanf("%d%d%d", &n, &m, &k)) { for(int i = 0; i < n; i++) for(int j = 0; j < m; j++) s[i][j] = -INF; memset(used, false, sizeof used); int cnt = 0; for(int i = 0; i < k; i++) { scanf("%d%d%d", &a, &b, &c); if(c >= 0) { s[a][b] = c; if(used[b] == false) used[b] = true, cnt++; } } if(k == 0 || n > cnt) { printf("Case %d: -1\n", ++x); continue; } nx = n, ny = m; memset(match, -1, sizeof match); km(); int res = 0; cnt = 0; for(int i = 0; i < m; i++) { if(match[i] != -1) res += s[match[i]][i], cnt++;; } if(cnt == n) printf("Case %d: %d\n", ++x, res); else printf("Case %d: -1\n", ++x); } return 0; }