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 好题~的更多相关文章

  1. 【转】POJ百道水题列表

    以下是poj百道水题,新手可以考虑从这里刷起 搜索1002 Fire Net1004 Anagrams by Stack1005 Jugs1008 Gnome Tetravex1091 Knight ...

  2. POJ题目细究

    acm之pku题目分类 对ACM有兴趣的同学们可以看看 DP:  1011   NTA                 简单题  1013   Great Equipment     简单题  102 ...

  3. 1047 Student List for Course ——PAT甲级真题

    1047 Student List for Course Zhejiang University has 40,000 students and provides 2,500 courses. Now ...

  4. 周赛C题 LightOJ 1047 (DP)

    C - C Time Limit:500MS     Memory Limit:32768KB     64bit IO Format:%lld & %llu   Description Th ...

  5. BZOJ 1047 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 题意:见中文题面 思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小.所以可以考 ...

  6. POJ推荐50题

    此文来自北京邮电大学ACM-ICPC集训队 此50题在本博客均有代码,可以在左侧的搜索框中搜索题号查看代码. 以下是原文: POJ推荐50题1.标记“难”和“稍难”的题目可以看看,思考一下,不做要求, ...

  7. 北大ACM题库习题分类与简介(转载)

    在百度文库上找到的,不知是哪位大牛整理的,真的很不错! zz题 目分类 Posted by fishhead at 2007-01-13 12:44:58.0 -------------------- ...

  8. [NOIP 2014复习]第三章:动态规划——NOIP历届真题回想

    背包型动态规划 1.Wikioi 1047 邮票面值设计 题目描写叙述 Description 给定一个信封,最多仅仅同意粘贴N张邮票,计算在给定K(N+K≤40)种邮票的情况下(假定全部的邮票数量都 ...

  9. PAT-乙级-1047. 编程团体赛(20)

    1047. 编程团体赛(20) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 编程团体赛的规则为:每个参赛队由若 ...

随机推荐

  1. html5 canvas 涂鸦画板

    html5 canvas 的涂鸦画板,可以加载图片进行涂鸦,也可以下载服务器使用的php上传的图片不能超过1M,只能是jpg或者png 格式的演示地址的服务器网速不怎么样,读取文件可能很慢,到达100 ...

  2. jsp报An error has occurred. See error log for more details. Argument not valid错误

    An error has occurred. See error log for more details. Argument not valid 翻译过来是:一个错误已经发生.看到更多的细节错误日志 ...

  3. php数组合并

    php的数合并函数: array_merge($arr1, $arr2, ..., $arr{$n}); 如果数组的键名有重复,后面的会覆盖前面的. 如果键名是数字索引,则会重新排列索引,往后累加. ...

  4. [LeetCode] Scramble String -- 三维动态规划的范例

    (Version 0.0) 作为一个小弱,这个题目是我第一次碰到三维的动态规划.在自己做的时候意识到了所谓的scramble实际上有两种可能的类型,一类是在较低层的节点进行的两个子节点的对调,这样的情 ...

  5. eclipse Tomcat 启动报错

    如果之前启动都是正常的,更新完后端代码后启动Tomcat报错,又没有错误的日志提示. 尝试先把Tomcat里面的项目删掉,然后点击Tomcat右键,Clean清除缓存,再把项目Add: 重新启动!

  6. java并发之阻塞队列LinkedBlockingQueue与ArrayBlockingQueue

    Java中阻塞队列接口BlockingQueue继承自Queue接口,并提供put.take阻塞方法.两个主要的阻塞类实现是ArrayBlockingQueue和LinkedBlockingQueue ...

  7. 洛谷 1312 Mayan游戏——暴搜+剪枝

    题目:https://www.luogu.org/problemnew/show/P1312 自己写了很久.又T又WA的. 发现对题理解有误.改完后应该只有T了,但还是T的. 自己写了许多剪枝,很鸡肋 ...

  8. bzoj 2006 [NOI2010]超级钢琴——ST表+堆

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2006 每个右端点的左端点在一个区间内:用堆记录端点位置.可选区间,按价值排序:拿出一个后也许 ...

  9. 使用Node.js实现简单的网络爬取

    由于最近要实现一个爬取H5游戏的代理服务器,隧看到这么一篇不错的文章(http://blog.miguelgrinberg.com/post/easy-web-scraping-with-nodejs ...

  10. Win10设置vs2010总是以管理员身份运行

    有的项目用vs打开后直接运行总是要求提升权限,如下图       1.第一步(这样的方式只能是先运行vs,然后再打开项目,这样才是以管理员的身份运行的.但是如果是通过sln文件的快捷方式打开的,却不是 ...