hdu 2853 Assignment KM算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853
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.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
using namespace std;
const int maxn=; int n,m,k,sum;
int lx[maxn],ly[maxn],visx[maxn],visy[maxn];
int link[maxn],slack[maxn],w[maxn][maxn];
int vis[maxn][maxn]; int dfs(int x)
{
visx[x]=;
for (int y= ;y<=m ;y++)
{
if (visy[y]) continue;
int t=lx[x]+ly[y]-w[x][y];
if (t==)
{
visy[y]=;
if (link[y]==- || dfs(link[y]))
{
link[y]=x;
return ;
}
}
else if (slack[y]>t) slack[y]=t;
}
return ;
} void KM()
{
memset(link,-,sizeof(link));
memset(ly,,sizeof(ly));
for (int i= ;i<=n ;i++)
{
lx[i]=-inf;
for (int j= ;j<=m ;j++)
lx[i]=max(lx[i],w[i][j]);
}
for (int x= ;x<=n ;x++)
{
for (int i= ;i<=m ;i++) slack[i]=inf;
while ()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if (dfs(x)) break;
int d=inf;
for (int i= ;i<=m ;i++)
{
if (!visy[i] && slack[i]<d) d=slack[i];
}
for (int i= ;i<=n ;i++)
if (visx[i]) lx[i] -= d;
for (int i= ;i<=m ;i++)
{
if (visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
}
int ans=,cnt=;
for (int i= ;i<=m ;i++)
{
if (link[i]!=-)
{
ans += w[link[i] ][i];
if (vis[link[i] ][i]) cnt++;
}
}
printf("%d %d\n",n-cnt,ans-sum-cnt);
// for (int i=1 ;i<=m ;i++)
// {
// if (link[i]!=-1) ans += w[link[i] ][i];
// }
// printf("%d %d\n",n-ans%k,ans/k-sum);
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(w,,sizeof(w));
memset(vis,,sizeof(vis));
k=;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=m ;j++)
{
scanf("%d",&w[i][j]);
/// w[i][j] *= k;
}
}
int a;
sum=;
for (int i= ;i<=n ;i++)
{
scanf("%d",&a);
sum += w[i][a];
///sum += w[i][a]/k;
w[i][a] ++ ;
vis[i][a]=;
}
KM();
}
return ;
}
方法二:和方法一的区别就在于对每条边都乘以k(比如k=200),对于原有匹配w[x][y]++,最后的答案最大效率为ans。
那么差值=ans/k-sum;个数=n-ans%k。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
#define inf 0x7fffffff
using namespace std;
const int maxn=; int n,m,k,sum;
int lx[maxn],ly[maxn],visx[maxn],visy[maxn];
int link[maxn],slack[maxn],w[maxn][maxn]; int dfs(int x)
{
visx[x]=;
for (int y= ;y<=m ;y++)
{
if (visy[y]) continue;
int t=lx[x]+ly[y]-w[x][y];
if (t==)
{
visy[y]=;
if (link[y]==- || dfs(link[y]))
{
link[y]=x;
return ;
}
}
else if (slack[y]>t) slack[y]=t;
}
return ;
} void KM()
{
memset(link,-,sizeof(link));
memset(ly,,sizeof(ly));
for (int i= ;i<=n ;i++)
{
lx[i]=-inf;
for (int j= ;j<=m ;j++)
lx[i]=max(lx[i],w[i][j]);
}
for (int x= ;x<=n ;x++)
{
for (int i= ;i<=m ;i++) slack[i]=inf;
while ()
{
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if (dfs(x)) break;
int d=inf;
for (int i= ;i<=m ;i++)
{
if (!visy[i] && slack[i]<d) d=slack[i];
}
for (int i= ;i<=n ;i++)
if (visx[i]) lx[i] -= d;
for (int i= ;i<=m ;i++)
{
if (visy[i]) ly[i] += d;
else slack[i] -= d;
}
}
}
int ans=,cnt=;
for (int i= ;i<=m ;i++)
{
if (link[i]!=-) ans += w[link[i] ][i];
}
printf("%d %d\n",n-ans%k,ans/k-sum);
} int main()
{
while (scanf("%d%d",&n,&m)!=EOF)
{
memset(w,,sizeof(w));
k=;
for (int i= ;i<=n ;i++)
{
for (int j= ;j<=m ;j++)
{
scanf("%d",&w[i][j]);
w[i][j] *= k;
}
}
int a;
sum=;
for (int i= ;i<=n ;i++)
{
scanf("%d",&a);
sum += w[i][a]/k;
w[i][a] ++ ;
}
KM();
}
return ;
}
hdu 2853 Assignment KM算法的更多相关文章
- 【HDU 2853】 KM算法
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题意:有n个公司,m个任务,每个公司做每个任务都有一个效率值,最开始每个公司都指派了一个任务,现 ...
- HDU 2853 Assignment(KM最大匹配好题)
HDU 2853 Assignment 题目链接 题意:如今有N个部队和M个任务(M>=N),每一个部队完毕每一个任务有一点的效率,效率越高越好.可是部队已经安排了一定的计划,这时须要我们尽量用 ...
- HDU(2255),KM算法,最大权匹配
题目链接 奔小康赚大钱 Time Limit: 1000/1000MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Su ...
- HDU 2853 最大匹配&KM模板
http://acm.hdu.edu.cn/showproblem.php?pid=2853 这道题初看了没有思路,一直想的用网络流如何解决 参考了潘大神牌题解才懂的 最大匹配问题KM 还需要一些技巧 ...
- HDU 2853 & 剩余系+KM模板
题意: 给你一张二分图,给一个原匹配,求原匹配改动最少的边数使其边权和最大. SOL: 我觉得我的智商还是去搞搞文化课吧..这种题给我独立做我大概只能在暴力优化上下功夫.. 这题的处理方法让我想到了剩 ...
- 【HDU 2853】Assignment (KM)
Assignment Problem Description Last year a terrible earthquake attacked Sichuan province. About 300, ...
- Assignment (HDU 2853 最大权匹配KM)
Assignment Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total ...
- Assignment HDU - 2853(二分图匹配 KM 新边旧边)
传送门: Assignment HDU - 2853 题意:题意直接那松神的题意了.给了你n个公司和m个任务,然后给你了每个公司处理每个任务的效率.然后他已经给你了每个公司的分配方案,让你求出最多能增 ...
- 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 ...
随机推荐
- float:left居中对齐
<div class="M1180"><div class="services"> <div class="serv_c ...
- 【转】src与href属性的区别
ref:http://www.jb51.net/web/77258.html src和href之间存在区别,能混淆使用.src用于替换当前元素,href用于在当前文档和引用资源之间确立联系. src是 ...
- C#中sizeof的用法实例分析
这篇文章主要介绍了C#中sizeof的用法,包括了常见的用法及注释事项,需要的朋友可以参考下. sizeof是C#中非常重要的方法,本文就以实例形式分析C#中sizeof的用法.分享给大家供大家参 ...
- Silverlight取得Session
首先Session是运行在服务器上的,而Silverlight运行在客户端.因此在Silverlight中使用SESSION的说法并不准确, 只因大家经常这样搜索才起这个名字. 有两种方法实现Silv ...
- Laravel 安装predis 扩展
在安装predis扩展之前先安装composer,安装教程在https://getcomposer.org/download/: php -r "copy('https://getcompo ...
- DXperience重编译汉化的方法
1. 必须有DXperience相应版本的全部源代码SourceCode.把全部源代码复制到\Program Files\Developer Express .NET vX.X\Sources目录.目 ...
- STM32F4_RCC系统时钟配置及描述
Ⅰ.概述 对于系统时钟应该都知道它的作用,就是驱动整个芯片工作的心脏,如果没有了它,就等于人没有了心跳. 对于使用开发板学习的朋友来说,RCC系统时钟这一块知识估计没怎么去配置过,原因在于开发板提供的 ...
- Python核心编程--学习笔记--5--数字
本章的主题是Python中的数字,这里详细介绍每一种数字类型,它们适用的各种运算符,以及用于处理数字的内建函数.在本章的末尾简单介绍了几个标准库中用于处理数字的模块. 1 数字类型 数字:标量贮存,可 ...
- [笔记]--Python字符串处理
一.截取字符串中的内容 1.截取: MsiExec.exe /I{AC76BA86-7AD7-2052-7B44-AB0000000001} 中的: {AC76BA86-7AD7-2052-7B44- ...
- 浅谈iOS网络编程之一入门
计算机网络,基本上可以抽象是端的通信.实际在通讯中会用到不同的设备,不同的硬件中,为了能友好的传输信息,那么建立一套规范就十分必要了.先来了解一些基本概念 了解网络中传输的都是二进制数据流. 2.了 ...