传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2853

Assignment

Time Limit: 2000/1000 MS (Java/Others)

Memory Limit: 32768/32768 K (Java/Others)

Problem Description

Last year a terrible earthquake attacked Sichuan province. About 300,000 PLA soldiers attended the rescue, also ALPCs. Our mission is to solve difficulty problems to optimization the assignment of troops. The assignment is measure by efficiency, which is an integer, and the larger the better.

We have N companies of troops and M missions, M>=N. One company can get only one mission. One mission can be assigned to only one company. If company i takes mission j, we can get efficiency Eij.

We have a assignment plan already, and now we want to change some companies’ missions to make the total efficiency larger. And also we want to change as less companies as possible.

Input

For each test case, the first line contains two numbers N and M. N lines follow. Each contains M integers, representing Eij. The next line contains N integers. The first one represents the mission number that company 1 takes, and so on.

1<=N<=M<=50, 1

Output

For each the case print two integers X and Y. X represents the number of companies whose mission had been changed. Y represents the maximum total efficiency can be increased after changing.

Sample Input

3 3

2 1 3

3 2 4

1 26 2

2 1 3

2 3

1 2 3

1 2 3

1 2

Sample Output

2 26

1 2


解题心得:

  • 题意就是先给你一个匹配,要你重新匹配,匹配之后的权值最大,并且要求你改变原先匹配次数要最小。

  • 匹配出来的权值最大,就是一个KM算法,但是要改变次数最小就要一点小技巧了,原本想的是在原先的匹配方案上加一就可以了,这样在面对大小一样的情况下可以优先选择,但是有个问题就是很可能加一之后和另一个更大值重合了。所以需要先乘以一个很大的值,在加一就可以可以避免重合的问题,也就是hash的问题。然后再直接对比现在的匹配情况和之前的匹配情况。


#include<bits/stdc++.h>
using namespace std;
const int maxn = 55;
int maps[maxn][maxn];
int ly[maxn],lx[maxn],match[maxn],pre_match[maxn],slack[maxn];
bool visx[maxn],visy[maxn];
int n,m; void init()
{
memset(ly,0,sizeof(ly));
memset(lx,0,sizeof(lx));
memset(match,-1,sizeof(match));
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
scanf("%d",&maps[i][j]);
maps[i][j] *= 100;
if(maps[i][j] > lx[i])
lx[i] = maps[i][j];
}
for(int i=1;i<=n;i++)
scanf("%d",&pre_match[i]);
} bool dfs(int x)
{
visx[x] = true;
for(int i=1;i<=m;i++)
{
if(visy[i])
continue;
int temp;
temp = lx[x] + ly[i] - maps[x][i];
if(!temp)
{
visy[i] = true;
if(match[i] == -1 || dfs(match[i]))
{
match[i] = x;
return true;
}
}
else if(temp < slack[i])
slack[i] = temp;
}
return false;
} int get_pre_sum()
{
int sum = 0;
for(int i=1;i<=n;i++)
{
sum += maps[i][pre_match[i]]/100;
maps[i][pre_match[i]]++;
if(maps[i][pre_match[i]] > lx[i])
lx[i] = maps[i][pre_match[i]];
}
return sum;
} void KM()
{
int pre_sum = get_pre_sum();
for(int i=1;i<=n;i++)
{
memset(slack,0x3f,sizeof(slack));
while(1)
{
memset(visx,0,sizeof(visx));
memset(visy,0,sizeof(visy));
if(dfs(i))
break; int temp = 0x3f3f3f3f;
for(int j=1;j<=m;j++)
if(!visy[j] && temp > slack[j])
temp = slack[j];
for(int j=1;j<=n;j++)
{
if(visx[j])
lx[j] -= temp;
}
for(int j=1;j<=m;j++)
{
if(visy[j])
ly[j] += temp;
else
slack[j] -= temp;
}
}
}
int ans1,ans2;
ans1 = ans2 = 0;
for(int i=1;i<=m;i++)
ans1 += maps[match[i]][i];
for(int i=1;i<=n;i++)
{
if(match[pre_match[i]] != i)//前后对比
ans2++;
}
printf("%d %d\n",ans2,ans1/100-pre_sum);
//也可以写成:printf("%d %d\n",ans1%100,ans1/100-pre_sum);
return ;
} int main()
{
while(~scanf("%d%d",&n,&m))
{
init();
KM();
}
return 0;
}

HUD:2853-Assignment(KM算法+hash)的更多相关文章

  1. hdu 2853 Assignment KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 Last year a terrible earthquake attacked Sichuan ...

  2. 【HDU 2853】 KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题意:有n个公司,m个任务,每个公司做每个任务都有一个效率值,最开始每个公司都指派了一个任务,现 ...

  3. HDU 2853 Assignment(KM最大匹配好题)

    HDU 2853 Assignment 题目链接 题意:如今有N个部队和M个任务(M>=N),每一个部队完毕每一个任务有一点的效率,效率越高越好.可是部队已经安排了一定的计划,这时须要我们尽量用 ...

  4. hdu 2426 Interesting Housing Problem 最大权匹配KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2426 For any school, it is hard to find a feasible ac ...

  5. 【UVA 11383】 Golden Tiger Claw (KM算法副产物)

    Omi, Raymondo, Clay and Kimiko are on new adventure- in search of new Shen Gong Wu. But EvilBoy Geni ...

  6. KM算法专题

    原文:http://972169909-qq-com.iteye.com/blog/1184514 题目地址:这里. 1)求图中所有环的总长度(环的长度不唯一)的最小值.当无法得到完备匹配时说明环不存 ...

  7. 匈牙利算法与KM算法

    匈牙利算法 var i,j,k,l,n,m,v,mm,ans:longint; a:..,..]of longint; p,f:..]of longint; function xyl(x,y:long ...

  8. 【HDU2255】奔小康赚大钱-KM算法

    Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description ...

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

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

随机推荐

  1. is null 的优化

    bk1gx7xwj9du6SELECT *  FROM HEADERS GJH WHERE ATTRIBUTE10 IS NULL FOR UPDATE 优化建议如下: 短期来说:建立一个索引来优化: ...

  2. [干货分享]AXURE整套高保真UI框架和元件组(白色风格)

      写在前面 强烈建议开始之前阅读以下第一篇高保真UI框架的前面部分,以了解设计思想,这篇文章不再重复介绍: AXURE-整套可复用的高保真元件和框架之暗黑风格 本次共享模板的UI规范 注:由于篇幅问 ...

  3. 啊哈算法之巧用队列解密QQ号

    简述 本算法摘选自啊哈磊所著的<啊哈!算法>第二章第一节的题目——使用队列来解密举例中按照规则加密的QQ号.文中代码使用C语言编写,博主通过阅读和理解,重新由Java代码实现了一遍,意在深 ...

  4. Java基本语法和变量

    1基本语法 1.1 标识符.关键字 在程序中用于定义名称的都为标识符,如文件名称.类名称.方法名称或变量名称等. 在Java中标识符的定义格式由字母.数字._(下划线),$所组成,不能以数字开头, 不 ...

  5. [uestc oj]H - 邱老师选妹子

    H - 邱老师选妹子 Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

  6. codeforce Gym 100500I Hall of Fame (水)

    题意:统计一些串中,字母的出现频率,不分大小写,找出现频率最高5个字符(相同频率优先取字典序大的),把他们的对应的值加起来判断以下是否大于62. 没出现的不算. #include<cstdio& ...

  7. Android(java)学习笔记114:Service生命周期

    1.Service的生命周期         Android中的Service(服务)与Activity不同,它是不能和用户交互,不能自己启动的,运行在后台的程序,如果我们退出应用的时候,Servic ...

  8. 用函数求lnx,lgx等

    https://blog.csdn.net/liujian20150808/article/details/50628061

  9. 2018.5.11 Java利用反射实现对象克隆

    package com.lanqiao.demo; /** * 创建人 * @author qichunlin * */ public class Person { private int id; p ...

  10. 通过脚本批量添加AD用户

    1.新建一个csv文件(逗号分隔的一种值文件) 内容为:放在C:\盘根目录下 test300 test300 .com test300 test301 test301 .com test301 tes ...