传送门: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. 转 Oracle 11g Rman – 08317错误

    在一次帮助客户解决归档满的过程中遭遇了此错误. 客户是新上线系统,11g版本.设置了归档清除脚本(脚本参考:http://www.ludatou.com/?p=766),结果发现以往没问题的脚本在此刻 ...

  2. mysql索引方式

    /* 所有MySQL列类型可以被索引.根据存储引擎定义每个表的最大索引数和最大索引长度. 所有存储引擎支持每个表至少16个索引,总索引长度至少为256字节.大多数存储引擎有更高的限制. 索引的存储类型 ...

  3. Android使用AchartEngine绘制曲线图

    1.在布局文件中加入LinearLayout布局,如下: <LinearLayout android:id="@+id/chart" android:orientation= ...

  4. 时间日期相关:Date类、DateFormat类、Calendar类

    1 Date类 类 Date 表示特定的瞬间,精确到毫秒. 1秒=1000毫秒 毫秒的0点:公元1970年 一月一日,午夜0:00:00 对应的毫秒值就是0 时间和日期的计算,必须依赖毫秒值. Sys ...

  5. BZOJ3004: 吊灯(结论 毒瘤)

    题意 $n$个节点的树,判断能否划分成$\frac{n}{k}$个大小为$k$的联通块 Sol 首先$k$必须是$n$的倍数. 然后刚开始我就非常傻的以为输出所有约数就行了.. 但是图是这样,$k = ...

  6. 关于vue-resource 转变成axios的过程

    在做东钿贷后系统的时候,我选择了vue-resource这个插件作为与服务器沟通工具,但是听说前端同行说vuejs2.0已经不在维护vue-resource了,vuejs2.0 已经使用了axios了 ...

  7. keil下JLINK在线调试仿真设置,SWD连接

    keil下JLINK在线调试仿真设置,以下三个步骤搞定: 有时我们编译时会遇到空间不足的情况,首先我们应该把 flash和RAM的size 设置为当前所用芯片的大小,如下我使用了一个片上flash 2 ...

  8. MySQL-基本概念

    一.Mysql逻辑架构 引用自<高性能Mysql> 二.并发控制 读写锁:读锁是共享的,写锁是排他的,会阻塞其他的写锁和读锁. 锁粒度:表锁.行级锁 三.事务 事务(ACID特性):原子性 ...

  9. 单链表常见面试题(C语言实现)

    总结常见的单链表操作函数,复习使用,仅供参考,代码调试通过. #include<stdio.h> typedef struct node{ int data; struct node *n ...

  10. 将一个字符与对应Ascii码互转

    package nicetime.com.practies; /** * Java中将一个字符与对应Ascii码互转 1 byte = 8bit 可以表示 0-127 */public class G ...