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 ...
随机推荐
- [原创] 初识Agile/CMMI/Scrum
一.背景介绍 在朋友(aehyok)的建议下,初步去了解Visual Studio Online,简称VS Online(即原来的 Team Foundation Service,简称TFS) VS ...
- vue.js插件使用(02) vue-router
概述 vue-router是Vue.js官方的路由插件,它和vue.js是深度集成的,适合用于构建单页面应用.vue的单页面应用是基于路由和组件的,路由用于设定访问路径,并将路径和组件映射起来.传统的 ...
- ajax+php+mysql更新
html代码 <input type="button" id="quxiao" class="quxiao" name="q ...
- MongoDB中通过MapReduce实现合计Sum功能及返回格式不一致问题分析
建立下述测试数据,通过MapReduce统计每个班级学生数及成绩和. 代码如下: public string SumStudentScore() { var collection = _dataBas ...
- IOS学习4
---恢复内容开始--- UIScrollView 屏幕展示有限,超出一个屏时用户可滚动查看过多部分.UIView不具备滚动功能. -取消autolayout -设置CGSize contentSiz ...
- for xml path('') 引发的数据不完整
When you read Extensible Markup Language (XML) data from Microsoft SQL Server by using the SqlDataRe ...
- MapReduce shuffle阶段详解
在Mapreduce中,Shuffle过程是Mapreduce的核心,它分布在Mapreduce的map阶段和reduce阶段,共可分为6个详细的阶段: 1).Collect阶段:将MapTask的结 ...
- 开始认真学计算机网络----computer network学习笔记(一)
什么是计算机网络,就是连一堆计算机,计算机不单单指pc,还包括打印机啦,手机啦巴拉巴拉一堆 为什么要连,share data共享数据 数据? 文档,图片,视频,巴拉巴拉 网络有什么类型? LAN--- ...
- PAT乙级真题1001. 害死人不偿命的(3n+1)猜想 (15)(解题)
卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...
- 九度oj 1528 最长回文子串
原题链接:http://ac.jobdu.com/problem.php?pid=1528 小白书上的做法,不过这个还要简单些... #include<algorithm> #includ ...