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

题意:给一个n-m二分图,边权用一个n*m的矩阵表示,给出初始匹配,求二分图完美匹配相比初始匹配改变了几条边以及改变的数值

这类题的主要思想是增加原配边的权值,但又不影响最后结果。

步骤1:观察顶点数,每条边乘一个大于顶点数的数v

步骤2:对于原配边,每边加1(注意步骤2可以保证km()/v的结果与原结果相同)

步骤3:求完美匹配,答案为res,改变的边数=n-res%v(res%v表示完美匹配中有多少边属于原匹配),要求的完美匹配答案=res/v

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=;
const int INF=0x3f3f3f3f;
int nx,ny;
int linker[N],lx[N],ly[N],slack[N];
int visx[N],visy[N],w[N][N];
int DFS(int x)
{
visx[x]=;
for(int y=;y<=ny;y++){
if(visy[y])
continue;
int tmp=lx[x]+ly[y]-w[x][y];
if(tmp==){
visy[y]=;
if(linker[y]==- || DFS(linker[y])){
linker[y]=x;
return ;
}
}else if(slack[y]>tmp){
slack[y]=tmp;
}
}
return ;
}
int change ;
int KM()
{
int i,j;
memset(linker,-,sizeof(linker));
memset(ly,,sizeof(ly));
for(i=;i<=nx;i++)
for(j=,lx[i]=-INF;j<=ny;j++)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
for(int x=;x<=nx;x++){
for(i=;i<=ny;i++)
slack[i]=INF;
while(){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(DFS(x))
break;
int d=INF;
for(i=;i<=ny;i++)
if(!visy[i] && d>slack[i])
d=slack[i];
for(i=;i<=nx;i++)
if(visx[i])
lx[i]-=d;
for(i=;i<=ny;i++)
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;
}
}
int res=;
for(i=;i<=ny;i++)
if(linker[i]!=-)
res+=w[linker[i]][i];
change=nx-res% ;
return res/;
}
int main()
{
while(~scanf("%d%d",&nx,&ny))
{
for(int i=;i<=nx;i++)
for(int j=;j<=ny;j++)
{
scanf("%d",&w[i][j]);
w[i][j]*= ;
}
int res= ;
for(int i= ;i<=nx ;i++)
{
int x ;
scanf("%d",&x) ;
res+=w[i][x] ;
w[i][x]++ ;
}
int ans=KM();
printf("%d %d\n",change,ans-res/);
}
return ;
}

http://acm.hdu.edu.cn/showproblem.php?pid=3315

与2853一样思路的题目,区别是这题图没有直接给,要先算一下

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int N=;
const int INF=0x3f3f3f3f;
int n,nx,ny;
int linker[N],lx[N],ly[N],slack[N];
int visx[N],visy[N],w[N][N];
int DFS(int x)
{
visx[x]=;
for(int y=;y<=ny;y++){
if(visy[y])
continue;
int tmp=lx[x]+ly[y]-w[x][y];
if(tmp==){
visy[y]=;
if(linker[y]==- || DFS(linker[y])){
linker[y]=x;
return ;
}
}else if(slack[y]>tmp){
slack[y]=tmp;
}
}
return ;
}
int change ;
int KM()
{
int i,j;
memset(linker,-,sizeof(linker));
memset(ly,,sizeof(ly));
for(i=;i<=nx;i++)
for(j=,lx[i]=-INF;j<=ny;j++)
if(w[i][j]>lx[i])
lx[i]=w[i][j];
for(int x=;x<=nx;x++){
for(i=;i<=ny;i++)
slack[i]=INF;
while(){
memset(visx,,sizeof(visx));
memset(visy,,sizeof(visy));
if(DFS(x))
break;
int d=INF;
for(i=;i<=ny;i++)
if(!visy[i] && d>slack[i])
d=slack[i];
for(i=;i<=nx;i++)
if(visx[i])
lx[i]-=d;
for(i=;i<=ny;i++)
if(visy[i])
ly[i]+=d;
else
slack[i]-=d;
}
}
int res=;
for(i=;i<=ny;i++)
if(linker[i]!=-)
res+=w[linker[i]][i];
if(res<=)return - ;
change=nx-res% ;
return res/;
}
int V[N],H1[N],A1[N],H2[N],A2[N] ;
int main()
{
while(~scanf("%d",&n),n)
{
nx=ny=n ;
for(int i= ;i<=n ;i++)
scanf("%d",&V[i]) ;
for(int i= ;i<=n ;i++)
scanf("%d",&H1[i]) ;
for(int i= ;i<=n ;i++)
scanf("%d",&H2[i]) ;
for(int i= ;i<=n ;i++)
scanf("%d",&A1[i]) ;
for(int i= ;i<=n ;i++)
scanf("%d",&A2[i]) ;
for(int i=;i<=n;i++)
for(int j=;j<=n;j++)
{
int x ;
x=H1[i]/A2[j] ;
if(H1[i]%A2[j])x++ ;
if(x*A1[i]>=H2[j])w[i][j]=V[i]* ;
else w[i][j]=(-V[i]*) ;
}
for(int i= ;i<=n ;i++)
w[i][i]++ ;
int ans=KM();
if(ans==-)puts("Oh, I lose my dear seaco!") ;
else printf("%d %.3lf%%\n",ans,(nx-change)*100.0/n);
}
return ;
}

HDU 2853 && HDU 3315的更多相关文章

  1. 【HDU 2853】Assignment (KM)

    Assignment Problem Description Last year a terrible earthquake attacked Sichuan province. About 300, ...

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

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

  3. Assignment HDU - 2853(二分图匹配 KM 新边旧边)

    传送门: Assignment HDU - 2853 题意:题意直接那松神的题意了.给了你n个公司和m个任务,然后给你了每个公司处理每个任务的效率.然后他已经给你了每个公司的分配方案,让你求出最多能增 ...

  4. HDU - 2222,HDU - 2896,HDU - 3065,ZOJ - 3430 AC自动机求文本串和模式串信息(模板题)

    最近正在学AC自动机,按照惯例需要刷一套kuangbin的AC自动机专题巩固 在网上看过很多模板,感觉kuangbin大神的模板最为简洁,于是就选择了用kuangbin大神的模板. AC自动机其实就是 ...

  5. HDU 2853 最大匹配&KM模板

    http://acm.hdu.edu.cn/showproblem.php?pid=2853 这道题初看了没有思路,一直想的用网络流如何解决 参考了潘大神牌题解才懂的 最大匹配问题KM 还需要一些技巧 ...

  6. HDU 2853 (KM最大匹配)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2853 题目大意:二分图匹配费用流.①最大匹配②最小原配变动 解题思路: 如果去掉第二个要求,那么就是裸 ...

  7. 【HDU 2853】 KM算法

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

  8. hdu 2853 Assignment KM算法

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

  9. Assignment (HDU 2853 最大权匹配KM)

    Assignment Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

随机推荐

  1. selenium-firefox-headless

    from selenium import webdriver import time fireFoxOptions = webdriver.FirefoxOptions() fireFoxOption ...

  2. selenium_webdriver(python)获取元素属性值,浏览器窗口控制、网页前进后退,title/url打印

    <span style="font-family: Arial, Helvetica, sans-serif;"><span style="font-s ...

  3. CentOS下的Autoconf和AutoMake(实践篇) 2

    阅读过<Linux下的Autoconf和AutoMake(理论篇)>之后,进入到实践环节.实验环境:CentOS release 6.7 (Final) x64 1.检查一下这4个工具是否 ...

  4. C#中的?

    1. 可空类型修饰符(?):引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空.例如:string str=null; 是正确的,int i=null; 编译器就会报错.为了使值类型也 ...

  5. 使用MyBatis Generator自动生成实体、mapper和dao层

    原文链接 通过MyBatis Generator可以自动生成实体.mapper和dao层,记录一下怎么用的. 主要步骤: 关于mybatis从数据库反向生成实体.DAO.mapper: 参考文章:ht ...

  6. 合并两个dt

    C#代码中实现两个表(DataTable)的关联查询(JOIN)   之前通常都是使用SQL直接从数据库中取出表1和表2关联查询后的数据,只需要用一个JOIN就可以了,非常方便.近日遇到一种情况,两个 ...

  7. linux使用flock文件锁

    使用linux flock 文件锁实现任务锁定,解决冲突 格式: flock [-sxun][-w #] fd# flock [-sxon][-w #] file [-c] command flock ...

  8. loj#101. 最大流 dinic+当前弧

    板子题 当前弧优化版本 目前效率最高 //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize(&q ...

  9. 登录XML

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orient ...

  10. dp练习(5)——最长严格上升子序列

    1576 最长严格上升子序列  时间限制: 1 s  空间限制: 256000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 给一个数组a1, a2 ... ...