【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)

Supervisor, Supervisee
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 2538   Accepted: 719

Description

Suppose some supervisors each get to hire a new person for their department. There are N people to be placed in these N departments. Each supervisor interviews all N people, and ranks them according to how much she wants each of
them in her department (1 being "really want" and N being "really don't want"). In turn, each of the N candidates ranks each of the supervisors as to how much that person would like to work for that supervisor (again, 1 is "really want to work for him/her"
and N is "really don't want to work for him/her"). Given the scores that each supervisor has for each candidate, and the scores each candidate has for each manager, write a computer program to determine the "best match" of candidates to supervisors. The "best
match" is determined by finding the distribution that leads to the highest overall (i.e. sum of) satisfaction for all people. The closer a person is to her number one choice, the better. If everyone gets their number one choice, the average difference will
be 0.

Input

The first line of the input will contain a single integer greater than 0 specifying the number of test cases.



The next line will contain a single integer value N, 0 < N < 15, representing the number of supervisors (and the number of employees - there are N supervisors and N employees). The next N lines will be the preferences of each of the N supervisors. Each line
will contain N integer entries (1 through N for employees 1 through N), each separated by a space character, that represents the preferences of that supervisor from most preferred to least preferred. More specifically, the first entry on the line will represent
that supervisor's first choice, the second entry her second, and so on. The next N lines will be the preferences of the N employees, in the same format as the supervisors.



All lines of data in the input file will end with an empty line.

Output

For each test case, write the test case number (starting with 1) followed by the best average difference written to six digits of precision to the right of the decimal point. On the next line, show which best match it was (starting
with 1). On the next N lines, show each supervisor (starting with 1) followed by the employee with which she was matched (1 per line). NOTE: if there is more than one best match, matches should be listed in ascending permuted order (see sample output).



Separate each data set with an empty line.

Sample Input

2
7
1 2 3 4 5 6 7
2 1 3 4 5 6 7
3 1 2 4 5 6 7
4 1 2 3 5 6 7
5 1 2 3 4 6 7
6 1 2 3 4 5 7
7 1 2 3 4 5 6
1 2 3 4 5 6 7
2 1 3 4 5 6 7
3 1 2 4 5 6 7
4 1 2 3 5 6 7
5 1 2 3 4 6 7
6 1 2 3 4 5 7
7 1 2 3 4 5 6 2
1 2
2 1
1 2
1 2

Sample Output

Data Set 1, Best average difference: 0.000000
Best Pairing 1
Supervisor 1 with Employee 1
Supervisor 2 with Employee 2
Supervisor 3 with Employee 3
Supervisor 4 with Employee 4
Supervisor 5 with Employee 5
Supervisor 6 with Employee 6
Supervisor 7 with Employee 7 Data Set 2, Best average difference: 0.250000
Best Pairing 1
Supervisor 1 with Employee 1
Supervisor 2 with Employee 2

Source

题目大意就是n个上司与n名员工。每一个上司相应有想要搭配的员工。相同每一个员工有渴望搭配的上司。

输入第一行为N 之后n行为1~n号上司的期望 从左到右从最好到最差

相同之后n行是1~n号员工

匹配到最渴望的人值为0,否则从左到右一次加1

要求问平均期望的最小值,也就是最小值/2n

最小值用KM最小权匹配计算就可以,因为还要求输出解,有多解则输出多解。所以还要搜一下……

事实上数据非常少。找最小权匹配也用搜的也能够。

代码例如以下:

#include <iostream>
#include <cmath>
#include <vector>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <queue>
#include <list>
#include <algorithm>
#include <map>
#include <set>
#define LL long long
#define fread() freopen("in.in","r",stdin)
#define fwrite() freopen("out.out","w",stdout) using namespace std;
const int INF = 0x3f3f3f3f;
const int msz = 10000;
const double eps = 1e-8; int mp[23][33];
int lx[33],ly[33],link[33],slack[33],next[33];
bool visx[33],visy[33],vis[33];
int n,ans,cnt; bool cal(int x)
{
visx[x] = 1; for(int y = 0; y < n; ++y)
{
if(visy[y]) continue; int t = lx[x]+ly[y]-mp[x][y];
if(t == 0)
{
visy[y] = 1;
if(link[y] == -1 || cal(link[y]))
{
link[y] = x;
return 1;
}
}
else slack[y] = min(slack[y],t);
}
return 0;
} int KM()
{
memset(link,-1,sizeof(link)); for(int i = 0; i < n; ++i)
{
memset(slack,INF,sizeof(slack));
while(1)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy)); if(cal(i)) break; int d = INF;
for(int i = 0; i < n; ++i)
if(!visy[i]) d = min(d,slack[i]); for(int i = 0; i < n; ++i)
if(visx[i]) lx[i] -= d; for(int i = 0; i < n; ++i)
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
} ans = 0;
for(int i = 0; i < n; ++i)
if(link[i] != -1) ans += mp[link[i]][i]; return -ans;
} void dfs(int id,int hs)
{
if(hs < ans) return;
if(id == n)
{
if(hs == ans)
{
printf("Best Pairing %d\n",++cnt);
for(int i = 0; i < n; ++i)
{
printf("Supervisor %d with Employee %d\n",i+1,next[i]+1);
}
}
return;
} for(int i = 0; i < n; ++i)
{
if(vis[i]) continue;
vis[i] = 1;
next[id] = i;
dfs(id+1,hs+mp[id][i]);
vis[i] = 0;
}
} int main()
{
int t,x;
scanf("%d",&t); for(int z = 1; z <= t; ++z)
{
scanf("%d",&n);
memset(ly,0,sizeof(ly)); for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
{
scanf("%d",&x);
mp[x-1][i] = -j;
} for(int i = 0; i < n; ++i)
for(int j = 0; j < n; ++j)
{
scanf("%d",&x);
mp[i][x-1] -= j;
if(j == 0) lx[i] = mp[i][x-1];
else lx[i] = max(lx[i],mp[i][x-1]);
} printf("Data Set %d, Best average difference: %.6f\n",z,KM()*0.5/n); cnt = 0;
memset(vis,0,sizeof(vis));
dfs(0,0);
puts("");
} return 0;
}

【POJ 2400】 Supervisor, Supervisee(KM求最小权匹配)的更多相关文章

  1. poj 2195(KM求最小权匹配)

    题目链接:http://poj.org/problem?id=2195 思路:我们都知道KM使用来求最大权匹配的,但如果要求最小权匹配,只需把图中的权值改为负值,求一次KM,然后权值和取反即可. ht ...

  2. 【POJ 2195】 Going Home(KM算法求最小权匹配)

    [POJ 2195] Going Home(KM算法求最小权匹配) Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submiss ...

  3. POJ 2400 Supervisor, Supervisee(KM二分图最大权值匹配)题解

    题意:n个老板n个员工,先给你n*n的数据,i行j列代表第i个老板第j喜欢的员工是谁,再给你n*n的数据,i行j列代表第i个员工第j喜欢的老板是谁,如果匹配到第k喜欢的人就会产生一个分数k-1.现在让 ...

  4. POJ 2400 Supervisor, Supervisee(KM)

    題目鏈接 題意 :N个部门和N个员工,每个部门要雇佣一个工人,部门对每个工人打分,从1~N,1表示很想要,N表示特别不想要,每个工人对部门打分,从1~N.1表示很想去这个部门,N表示特别不想去这个部门 ...

  5. Fixed Partition Memory Management UVALive - 2238 建图很巧妙 km算法左右顶点个数不等模板以及需要注意的问题 求最小权匹配

    /** 题目: Fixed Partition Memory Management UVALive - 2238 链接:https://vjudge.net/problem/UVALive-2238 ...

  6. poj 3686(拆点+最小权匹配)

    题目链接:http://poj.org/problem?id=3686 思路:显然工件为X集,机器为Y集合.由于每个机器一次只能加工一个部件,因此我们可以将一台机器拆成N个点,至于部件与机器之间连多大 ...

  7. POJ 2400 最小权匹配

    吐槽:首先,这道题的输入居然是错的.要将上下两个矩阵的位置换一下才可以出样例,也就是上面那个矩阵是employee对Supervisor的打分,下面那个矩阵才是Supervisor对employee的 ...

  8. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  9. Poj(3686),最小权匹配,多重匹配,KM

    题目链接 The Windy's | Time Limit: 5000MS | Memory Limit: 65536K | | Total Submissions: 4939 | Accepted: ...

随机推荐

  1. MY97 日期控件只输入今天之前的值

    <script type="text/javascript">                        function GetDate() {          ...

  2. HDU 1698.Just a Hook-线段树(成段替换、输出总和tree[1])

    HDU1698.Just a Hook 这个题是最最基础的成段更新的线段数的题目,直接贴代码吧. 代码: #include<iostream> #include<cstring> ...

  3. 洛谷 P3378 【模板】堆

    如题,初始小根堆为空,我们需要支持以下3种操作: 操作1: 1 x 表示将x插入到堆中 操作2: 2 输出该小根堆内的最小数 操作3: 3 删除该小根堆内的最小数 输入输出格式 输入格式: 第一行包含 ...

  4. Linux下Shell的复制粘贴快捷键

    [Shift]+[Insert]:复制 [Ctrl]+[Insert]:粘贴

  5. Ubuntu 16.04服务器版查看DHCP自动分配的IP、网关、DNS

    说明: 1.在服务器版本中,没有想桌面版一样的NetworkManager工具,所以的一切都是在命令行上操作的. 2.本文只针对DHCP默认分配的IP进行查看. 方法: 1.如果要使用DHCP,那么需 ...

  6. IIS Express HTTP 错误 500.22

    错误描述: HTTP 错误 500.22 - Internal Server Error 检测到在集成的托管管道模式下不适用的 ASP.NET 设置. 最可能的原因: 此应用程序在 system.we ...

  7. 对于session序列化跟session的钝化与活化的粗浅理解

    1. API对序列化的解释:类通过实现 java.io.Serializable 接口以启用其序列化功能.未实现此接口的类将无法使其任何状态序列化或反序列化.可序列化类的所有子类型本身都是可序列化的. ...

  8. Keepalived高可用集群应用

    Keepalived高可用集群应用 1.keepalived服务说明 1.1.keepalived介绍 Keepalived是一个用C语言编写的路由软件.该项目的主要目标是为Linux系统和基于Lin ...

  9. Java程序猿的JavaScript学习笔记(12——jQuery-扩展选择器)

    计划按例如以下顺序完毕这篇笔记: Java程序猿的JavaScript学习笔记(1--理念) Java程序猿的JavaScript学习笔记(2--属性复制和继承) Java程序猿的JavaScript ...

  10. Win7 无法将快捷方式从任务栏移除怎么办

    不知道是什么修改了系统的属性了.在网上找到了这个方法解决了:一:为了解决这个问题,你可以尝试下面的方法:    把以下命令分别输入到开始-运行中    1.cmd /k reg add "H ...