题意:n个老板n个员工,先给你n*n的数据,i行j列代表第i个老板第j喜欢的员工是谁,再给你n*n的数据,i行j列代表第i个员工第j喜欢的老板是谁,如果匹配到第k喜欢的人就会产生一个分数k-1。现在让你给老板和员工配对,希望得到的分数的平均数最少,并给出哪个老板匹配哪个员工,多种情况按字典序输出。

思路:题目中的input提示是错的...

这题就是km最大权值匹配的裸题,分数最小那就把权值变负,然后跑出最少的总分。因为n比较小,可以dfs求出所有情况。

代码:

#include<set>
#include<map>
#include<stack>
#include<cmath>
#include<queue>
#include<vector>
#include<string>
#include<cstdio>
#include<cstring>
#include<sstream>
#include<iostream>
#include<algorithm>
typedef long long ll;
using namespace std;
const int maxn = + ;
const int MOD = 1e9 + ;
const int INF = 0x3f3f3f3f;
int nx, ny;
int g[maxn][maxn];
int linker[maxn], lx[maxn], ly[maxn];
int slack[maxn];
bool visx[maxn], visy[maxn];
bool dfs(int x){
visx[x] = true;
for(int y = ; y < ny; y++){
if(visy[y]) continue;
int tmp = lx[x] + ly[y] - g[x][y];
if(tmp == ){
visy[y] = true;
if(linker[y] == - || dfs(linker[y])){
linker[y] = x;
return true;
}
}
else if(slack[y] > tmp){
slack[y] = tmp;
}
}
return false;
}
int km(){
memset(linker, -, sizeof(linker));
memset(ly, , sizeof(ly));
for(int i = ; i < nx; i++){
lx[i] = -INF;
for(int j = ; j < ny; j++){
if(g[i][j] > lx[i]){
lx[i] = g[i][j];
}
}
}
for(int x = ; x < nx; x++){
for(int i = ; i < ny; 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 = ; i < ny; i++)
if(!visy[i] && d > slack[i])
d = slack[i];
for(int i = ; i < nx; i++)
if(visx[i])
lx[i] -= d;
for(int i = ; i < ny; i++){
if(visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
}
int res = ;
for(int i = ; i < ny; i++){
if(linker[i] != -)
res += g[linker[i]][i];
}
return res;
}
int ans[maxn], vis[maxn];
int n, t, ret, num, ca = ;
void DFS(int u, int sco){
if(sco < ret) return;
if(u == n){
if(sco == ret){
printf("Best Pairing %d\n", num++);
for(int i = ; i < n; i++){
printf("Supervisor %d with Employee %d\n", i + , ans[i]);
}
}
return;
}
for(int i = ; i < n; i++){
if(vis[i]) continue;
vis[i] = ;
ans[u] = i + ;
DFS(u + , sco + g[u][i]);
vis[i] = ;
}
}
int main(){
scanf("%d", &t);
while(t--){
num = ;
scanf("%d", &n);
memset(g, , sizeof(g));
for(int i = ; i < n; i++){ //雇员i对老板s
for(int j = ; j < n; j++){
int s;
scanf("%d", &s);
s--;
g[s][i] += -j;
}
}
for(int i = ; i < n; i++){ //老板i对雇员s
for(int j = ; j < n; j++){
int s;
scanf("%d", &s);
s--;
g[i][s] += -j;
}
}
nx = ny = n;
ret = km();
double f = -ret / 2.0 / n;
if(ca != ) printf("\n");
printf("Data Set %d, Best average difference: %lf\n", ca++, f);
memset(vis, , sizeof(vis));
num = ;
DFS(, );
}
return ;
}

POJ 2400 Supervisor, Supervisee(KM二分图最大权值匹配)题解的更多相关文章

  1. HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

    二分图最大权值匹配问题.用KM算法. 最小权值的时候把权值设置成相反数 /*-------------------------------------------------------------- ...

  2. 二分图最大权值匹配 KM算法 模板

    KM算法详解+模板 大佬讲的太好了!!!太好了!!! 转载自:http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该 ...

  3. POJ 2195 Going Home 【二分图最小权值匹配】

    传送门:http://poj.org/problem?id=2195 Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submis ...

  4. POJ 2400 Supervisor, Supervisee(KM)

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

  5. HDU 2255 KM算法 二分图最大权值匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  6. 【模板】二分图最大权完美匹配KM算法

    hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...

  7. 【二分图最大权完美匹配】【KM算法】【转】

    [文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...

  8. 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577

    题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...

  9. 奔小康赚大钱 HDU - 2255(最大权值匹配 KM板题)

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

随机推荐

  1. django 网站的搭建(2)

    这里使用nginx+uwsgi的方法来搭建生产环境 1,pip3.5  install uwsgi 下载uwsgi ,这里就不做测试了,一般不会出错 2,将django与uwsgi连接在一起 毕竟ru ...

  2. Web API 跨域问题

    解决办法: 1.web.config <system.webServer> <handlers> <remove name="ExtensionlessUrlH ...

  3. Tornado安装

    Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快.得利于其 非阻塞的方式和对 epoll 的运用,Tornado ...

  4. ajax评论

    评论有好几种格式:有评论树.评论楼等的格式 发表评论注意事项: 1. 展示评论 1. 评论楼(Django模板语言渲染) 1. 从后端查询出所有的评论 2. 如果有父评论就展示父评论 2. 评论树 通 ...

  5. ClassThird

    动手动脑:  1,在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. 代码: public class Move_hands_Move_head {  public void show( ...

  6. 20165215 2017-2018-2 《Java程序设计》第3周学习总结

    20165215 2017-2018-2 <Java程序设计>第3周学习总结 教材学习内容总结 编程语言历经面向机器语言.面向过程语言.面向对象语言三个发展阶段. 面向对象语言的三个特点: ...

  7. 转:三值逻辑与NULL的处理方式

    来自:<Microsoft SQL SERVER 2008技术内幕 T-SQL查询>P7 在SQL中谓词(逻辑表达式)的可能值为TRUE.FALSE和UNKNOWN.这就是所谓的三值逻辑, ...

  8. AtCoder Beginner Contest 086 (ABCD)

    A - Product 题目链接:https://abc086.contest.atcoder.jp/tasks/abc086_a Time limit : 2sec / Memory limit : ...

  9. 自写Jquery插件 Menu

    原创文章,转载请注明出处,谢谢!https://www.cnblogs.com/GaoAnLee/p/9067543.html 可以结合我自写的Jquery插件Tab 一起使用哦 上一个整体效果 直接 ...

  10. OCR技术初识

    一.什么是OCR OCR英文全称是Optical Character Recognition,中文叫做光学字符识别.它是利用光学技术和计算机技术把印在或写在纸上的文字读取出来,并转换成一种计算机能够接 ...