1047 - Best couple 好题~
http://www.ifrog.cc/acm/problem/1047
思路很简单,跑一发floyd,然后再用km。
但是问题来了,这个有可能n != m。那怎么办?
其实可以补上一些不存在的点。来使得n = m。他们的权值就设置为0就好了。意思就是这些人的搭配,是对答案没有贡献的。注意不能设置为-inf。因为补上的那些点也是必须要选人的,只不过他们选了人,相当于没选而已(权值不存在。)如果设置为-inf的那些,那么他们就会把答案改了。
还有一个小trick的就是,一开始,我是把本来地图上的-1的那些点,更改为inf的,inf表示不连通,那么直接floyd就可以了不用特判那么多。那么问题又来了。如果跑了floyd后,还是不连通,那怎么办?他们的权值可是inf啊。组成新图的时候,同时也是需要把他们的权值设置为0的,也就是相当于没选。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL; #include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
const int maxn = 1e2 + ;
int e[maxn][maxn];
int TE[ * maxn][ * maxn];
int match[maxn];//match[col] = row
int vx[maxn],vy[maxn];
int fx[maxn],fy[maxn];
int n, m;
int dfs (int u) {
vx[u]=;
int i;
for (i=; i<=m; i++) { //筛选n个 导航员 col的值
if (vy[i]==&&fx[u]+fy[i]==e[u][i]) {
vy[i]=;
if (match[i]==||dfs(match[i])) {
match[i]=u;// match[col]=row;
return ;//搭配成功
}
}
}
return ;//我找不到啊,后面,就会执行km
}
void do_km() { //
int i,j;
int d=inf;
for (i=; i<=n; i++) { //遍历每一个驾驶员 row的值
if (vx[i]==) {
for (j=; j<=m; j++) { //对他进行遍历导航员 col的值
if (!vy[j]) {
if (d>(fx[i]+fy[j]-e[i][j])) {
d=fx[i]+fy[j]-e[i][j];
}
}
}
}
}
for (i=; i<=n; i++) {
if (vx[i]==) {
fx[i] -= d;
vx[i]=;//请0
}
if (vy[i]==) { //
fy[i] += d;
vy[i]=;//情0
}
}
return ;
}
int anskm() {
memset (vx,,sizeof(vx));
memset (vy,,sizeof(vy));
memset (fx,,sizeof(fx));
memset (fy,,sizeof(fy));
memset (match,,sizeof(match));
//km算法的一部分,先初始化fx,fy
for (int i=; i<=n; i++) { //遍历每一个驾驶员 row的值
fy[i]=;
fx[i]= -inf;//无穷小
for (int j=; j<=m; j++) { //遍历每一个导航员 col的值
if (fx[i]<e[i][j]) { //默契值
fx[i]=e[i][j];
}
}
}
for (int i=; i<=n; i++) { //遍历每一个驾驶员 row的值
memset (vx,,sizeof(vx));
memset (vy,,sizeof(vy));
while (!dfs(i)) {//如果他找不到搭配,就实现km算法
do_km();//km完后,还是会对这个想插入的节点进行dfs的,因为他还没搭配嘛
}
// if (t == m) break;
}
int ans=;
for (int i=; i<=m; i++) //遍历导航员,col的值
ans += e[match[i]][i];//输入的row是驾驶员,col是导航员
//match[i]:导航员i和驾驶员match[i]搭配了 match[col]=row;
return ans;
} void work() {
memset(TE, , sizeof TE);
memset(e, , sizeof e);
cin >> n >> m;
for (int i = ; i <= n + m; ++i) {
for (int j = ; j <= n + m; ++j) {
cin >> TE[i][j];
if (TE[i][j] == -) TE[i][j] = inf;
}
}
for (int k = ; k <= n + m; ++k) {
for (int i = ; i <= n + m; ++i) {
for (int j = ; j <= n + m; ++j) {
if (TE[i][j] > TE[i][k] + TE[k][j]) {
TE[i][j] = TE[i][k] + TE[k][j];
}
}
}
}
// for (int i = 1; i <= n + m; ++i) {
// for (int j = 1; j <= n + m; ++j) {
// cout << TE[i][j] << " ";
// }
// cout << endl;
// }
// cout << endl; for (int i = ; i <= n; ++i) {
for (int j = ; j <= m; ++j) {
e[i][j] = TE[i][n + j];
if (e[i][j] == inf) {
e[i][j] = ; //不联通,要用0代替
}
}
}
if (n > m) {
for (int i = ; i <= n; ++i) {
for (int j = m + ; j <= n; ++j) {
e[i][j] = ;
}
}
m = n;
} else if (n < m) {
for (int i = n + ; i <= m; ++i) {
for (int j = ; j <= m; ++j) {
e[i][j] = ;
}
}
n = m;
}
cout << anskm() << endl;
}
int main() {
#ifdef local
freopen("data.txt","r",stdin);
#endif
IOS;
int t;
cin >> t;
while (t--) work();
return ;
}
1047 - Best couple 好题~的更多相关文章
- 【转】POJ百道水题列表
以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...
- POJ题目细究
acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP: 1011 NTA 简单题 1013 Great Equipment 简单题 102 ...
- 1047 Student List for Course ——PAT甲级真题
1047 Student List for Course Zhejiang University has 40,000 students and provides 2,500 courses. Now ...
- 周赛C题 LightOJ 1047 (DP)
C - C Time Limit:500MS Memory Limit:32768KB 64bit IO Format:%lld & %llu Description Th ...
- BZOJ 1047 二维单调队列
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 题意:见中文题面 思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小.所以可以考 ...
- POJ推荐50题
此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...
- 北大ACM题库习题分类与简介(转载)
在百度文库上找到的,不知是哪位大牛整理的,真的很不错! zz题 目分类 Posted by fishhead at 2007-01-13 12:44:58.0 -------------------- ...
- [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想
背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...
- PAT-乙级-1047. 编程团体赛(20)
1047. 编程团体赛(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 编程团体赛的规则为:每个参赛队由若 ...
随机推荐
- Linux-awk和shell编程初步
1 awk 格式: awk -选项 '处理' 输入 awk -F : '{print $1}' file -F指定分隔符, 默认是空格 $1 分割后的第一部分 $0 获得所有部分 NF 表示以分隔符分 ...
- 在KitKat(Android 4.4.2) 推送网址给手机
弱者才会回避问题. 最近想把网址推送给手机实现后台下载,打算故技重施,用短信传送然后中断广播的方法实现隐蔽传送.试了半天发现怎么现在拦不住短信了.查了一下才发现原来Android4.4增加了一个安全机 ...
- ip策略路由
ip route 只是基于目的地址的路由选择 ip rule 路由策略,控制路由选择,可根据源地址,源IP等进行路由选择 路由策略由选择符合操作组成 ip rule add 添加策略 ip r ...
- UOJ309 UNR #2 排兵布阵
包含不小于$\sqrt n$列的只有不大于$\sqrt n$行,修改时这些行打标记,否则暴力更新,操作一列的时候暴力更新这些行.合并没啥影响直接搞就是了.更新需要访问位置,感觉必须用哈希表,并不是特别 ...
- MongoDB复制集相关方法使用(五)
这里我们把复制集中可用的方法都实验一遍,帮助我们更好地来理解复制集.提前说明这些方法的使用是基于Mongodb3.2版本来的,看这篇文章之前需要先看上一篇文章. 介绍一下复制集可用的相关方法 rs.h ...
- C/C++获取Windows系统CPU和内存及硬盘使用情况
//1.获取Windows系统内存使用率 //windows 内存 使用率 DWORD getWin_MemUsage(){ MEMORYSTATUS ms; ::GlobalMemoryStatus ...
- 【Boost】boost库asio详解3——io_service作为work pool
无论如何使用,都能感觉到使用boost.asio实现服务器,不仅是一件非常轻松的事,而且代码很漂亮,逻辑也相当清晰,这点上很不同于ACE.使用io_service作为处理工作的work pool,可以 ...
- linux 中的局部变量、全局变量、shell 变量的总结
系统局部变量和全局变量 一.变量分类局部变量和环境变量,局部变量只适用于当前shell,而环境变量是全局的,它适用于所有当前shell以及其派生出来的任意子进程,有些变量是用户创建的,其他的则是专用 ...
- samba 安装运行
samba 安装步骤 1.若之前有安装过相关软件包,先卸载之:sudo apt-get autoremove samba samba-commonsudo apt-get autoremove sys ...
- Bean的不同配置方式比较与应用场景
基于XML配置 Bean的定义: 在XML文件中通过<bean>元素定义. Bean的名称: 通过<bean>的id或name属性定义. ...