上次我们过了二分图的最佳匹配,现在我们看一道题目,经典的二分图的最佳匹配题目

8616 汽车拉力比赛

时间限制:500MS  内存限制:1000K
提交次数:71 通过次数:24

题型: 编程题   语言: G++;GCC

Description


 SCAU车队要去参加汽车拉力比赛啦。拉力比赛中,每辆汽车需要一个驾驶员和一个导航员。SCAU车队一共有有N个驾驶员和N个导航员,每个 驾驶员对每个导航员有一个默契值,现在需要求得某种N对N的配对,使得这N个配对的默契值之和最大。

输入格式

多Case,每一个Case第一行是一个整数N,范围是(1<=N<=16)。接下来有N行,每行有N个数,第i行第j个数表示第i个驾驶员和第j个导航员的默契值。 测试数据会有多组,当N=0时表示数据结束,这行不用处理。

输出格式

输出配对后默契值之和的最大值。

输入样例

1
5
2
10 20
25 5
0

输出样例

5
45
至于如何做,我就不说了,看看我以前的博客吧,思路应该很清晰的
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define inf 99999
//保存一个我们认为的无穷大
int n;
int match[];//表示这个[驾驶员]搭配那个驾驶员
int e[][];//用来保存一张图,表示i-->j的默契值
int vx[];//用来表示 驾驶员 来找过partner
int vy[];//用来表示 导航员 被邀请过搭配
int fx[];//一开始是用来表示每一个驾驶员与1--n个导航员的max,但是随着程序执行,会变化哦
int fy[];//一开始是0的。我们称这两个东西为 标干
int dfs (int u)//我要来找u的partner
{
vx[u]=;//u已经来找过partner啦,标记一下先,待会的km算法需要
int i;
for (i=;i<=n;i++)//筛选n个 导航员 可以知道,驾驶员比较“主动”
{
if (vy[i]==&&fx[u]+fy[i]==e[u][i])//这个导航员没有被邀请过..导航员为u
//驾驶员和导航员的【标杠】值相加,有这个默契值的话,这样选出来的是最优的
{
//vy[i]==1;//这个导航员被邀请过了,但是,接不接受?还是另外一回事
//不是等于等于
//因为他还可能是被别人搭配了嘛
vy[i]=;
if (match[i]==||dfs(match[i]))//如果他没被人搭配了或者,它可以找其他人搭配
{
match[i]=u;//i搭配u 改变条件的
//意思就是导航员i和驾驶员u搭配
return ;//搭配成功
}
}
}
return ;//我找不到啊,后面,就会执行km
}
void do_km()//km算法
//对每一个在vx[]数组中的驾驶员,我们对他进行操作
//操作对象是每一个不在vy[]数组中的导航员,在了的导航员是不能动的,是当前的最优解
{
int i,j;
int d;//表示默契值减小得最多,就是,搭配最大
d=inf;//认为他是无限大
for (i=;i<=n;i++)//遍历每一个驾驶员
{
if (vx[i]==)//表示他是遍历过的
{
for (j=;j<=n;j++)//对他进行遍历导航员
{
if (!vy[j])//没有vy过的导航员才操作
{
if (d>(fx[i]+fy[j]-e[i][j]))//对于后面没vy的导航员,选出最小差值
{
d=fx[i]+fy[j]-e[i][j];
//printf ("%d\n",d);
}
}
}
}
}
//对于每一个vx[]的 fx[] 减去d
//对于每一个vy[]的 fy[] 加上d
//这样,总值会减小哦,就是,我们有机会加入新的导航员,留下空位
for (i=;i<=n;i++)
{
if (vx[i]==)
{
fx[i] -= d;
vx[i]=;//请0
}
if (vy[i]==)//是访问过的哦
{
fy[i] += d;
vy[i]=;//情0
}
}
return ;
}
void work ()
{
int i,j;
memset (e,,sizeof(e));
memset (vx,,sizeof(vx));
memset (vy,,sizeof(vy));
memset (fx,,sizeof(fx));
memset (fy,,sizeof(fy));
memset (match,,sizeof(match)); for (i=;i<=n;i++)
{
for (j=;j<=n;j++)
{
scanf ("%d",&e[i][j]);//不是无向图哦,有向的
//就是e[i][j]!=e[j][i] 有可能相等
}
}
//km算法的一部分,先初始化fx,fy
for (i=;i<=n;i++)//遍历每一个驾驶员
{
fy[i]=;
fx[i]= -inf;//无穷小
for (j=;j<=n;j++)//遍历每一个导航员
{
if (fx[i]<e[i][j])//默契值
{
fx[i]=e[i][j];
}
}
}
for (i=;i<=n;i++)//遍历每一个驾驶员
{
memset (vx,,sizeof(vx));//每一个驾驶员都是新的开始
memset (vy,,sizeof(vy));//要清零,
while (!dfs(i))//如果他找不到搭配,就实现km算法
{
do_km();//km完后,还是会对这个想插入的节点进行dfs的,因为他还没搭配成功嘛
}
}
//进行计数
//现在match[i]记录的是[导航员i]和[驾驶员match[i]]搭配
int ans=;
for (i=;i<=n;i++)//遍历导航员
{
ans += e[match[i]][i];//输入的第一个是驾驶员,第二个是导航员
}
printf ("%d\n",ans);
return ;
}
int main ()
{
while (scanf ("%d",&n)!=EOF && n)
{
work ();
}
return ;
}
 

scau 8616 汽车拉力比赛的更多相关文章

  1. 洛谷——P2658 汽车拉力比赛

    P2658 汽车拉力比赛 题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些 ...

  2. P2658 汽车拉力比赛

    题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ≤500),每个单元格的海拔范围在0到10^9之间. 其中一些单元格被定义为路标.组织者 ...

  3. 洛谷—— P2658 汽车拉力比赛

    https://www.luogu.org/problem/show?pid=2658 题目描述 博艾市将要举行一场汽车拉力比赛. 赛场凹凸不平,所以被描述为M*N的网格来表示海拔高度(1≤ M,N ...

  4. 洛谷 P2658 汽车拉力比赛

    题目传送门 解题思路: 二分答案,然后bfs验证,如果从一个路标可以达到其它所有路标,则答案可行.知道找到最佳答案. AC代码: #include<iostream> #include&l ...

  5. 汽车制造商表态:必须依靠MES系统来管控流程

    汽车行业特点 汽车工业是一个高投入,高产出,集群式发展的产业部门. 汽车自身的投资,生产,研发,供应,销售,维修:前序的原材料,零部件,技术装备,物流:后序的油料,服务,信贷,咨询,保险,直至基础设施 ...

  6. New Concept English Two 22 58

    $课文56  比声音还快! 579. Once a year, a race is held for old cars. 旧式汽车的比赛每年举行一次. 580. A lot of cars enter ...

  7. [SD心灵鸡汤]003.每月一则 - 2015.07

    乔布斯去世了,但他留给世人的财富却很多,值得每个人学习.他是个精力充沛魅力无限的家伙,同时也是一个很会鼓动人心的激励大师,甚至在他的平常对话中,经典的语句也常常脱口而出. 这里摘取了一些他的经典语录, ...

  8. 【题解】Leyni的汽车比赛

    [题解]Leyni的汽车比赛 HRBUST - 1404 思维题?居然被我凑出来了 这种图论题先设这样一个状态 \[ ans(i,j,f) \] 表示从i到j,最多使用f个交通工具的最短路 转移的话, ...

  9. HLG 1400 汽车比赛

    题目链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1400 结构体排序+树状数 ...

随机推荐

  1. 2013 蓝桥杯校内选拔赛 java本科B组(题目+答案)

    一.标题:正则表示     正则表达式表示了串的某种规则或规律.恰当地使用正则表达式,可以使得代码简洁.事半功倍.java的很多API都支持正则表达式作为参数.其中的String.split就是这样. ...

  2. JVM插码之三:javaagent介绍及javassist介绍

    本文介绍一下,当下比较基础但是使用场景却很多的一种技术,稍微偏底层点,就是字节码插庄技术了...,如果之前大家熟悉了asm,cglib以及javassit等技术,那么下面说的就很简单了...,因为下面 ...

  3. CI框架 Fatal error: Call to undefined method CI_DB::CI_DB() in D:\xinqing\web\CodeIgniter\database\drivers\odbc\odbc_driver.php on line 53

    Fatal error: Call to undefined method CI_DB::CI_DB() in D:\xinqing\web\CodeIgniter\database\drivers\ ...

  4. numpy.matlib.randn(标准正态分布)

    #网址 http://docs.scipy.org/doc/numpy/reference/generated/numpy.matlib.randn.html#numpy.matlib.randn n ...

  5. 问题:C#发布的项目浏览时出现“Server Application Unavailable”错误;结果:Server Application Unavailable出现的原因及解决方案小结

    Server Application Unavailable出现的原因及解决方案小结 作者: 字体:[增加 减小] 类型:转载 时间:2012-05-23 今天在服务器安装了个.net 4.0 fra ...

  6. SSDB VS redis

    现在有不少团队开始使用了一个新型高效的 NoSQL数据库 - SSDB,如 京东.唱吧 …… SSDB 官网的定义 一个高性能的支持丰富数据结构的 NoSQL 数据库,用于替代 Redis 官网 ht ...

  7. 06_android虚拟机介绍 05_sdkManager介绍

    如果你不对SDK Manager进行设置,它默认会去谷歌官网下载最新的内容.由于官网被墙了,要么你FQ要么去设置代理.通过代理去下载相关的内容. 每一个android版本都对应着一个API的版本号.如 ...

  8. Java解析XML:Jdom解析和SAX解析

    今天看了Java解析XML的几种方法,记录一下 1.Jdom解析 (1)读取XML内容 private static void readXML() { // TODO Auto-generated m ...

  9. 在虚拟机中的Ubuntu搭建java开发环境

    前提: 安装好虚拟机 在虚拟机中装好了Ubuntu系统 以上两步请参见我的博客(python进阶) 1 安装JDK 1.1 到官网下载jdk压缩包并保存在本地 jdk1.8:点击前往 1.2 在Ubu ...

  10. SDK和JDK的区别

    刚开始工作时,还以为两者是一样的,只是版本换新给了个新名字罢了.最近又关注到这个问题,才发现自己大错特错,故整理了下分享给大家,共勉! jdk,是Java开发工具包,主要用于编写Java程序:也就是说 ...