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. CI 模型公用查询函数

    /** * 多字段条件查询数据 * @param array $val array("name" => $value).name为要操作的字段,value为要操作的值 * @ ...

  2. html5--3.18 新增的output元素

    html5--3.18 新增的output元素 学习要点 了解output元素的用法 output元素:数据的输出 output元素是HTML5新增的元素,用来设置不同数据的输出 output元素的输 ...

  3. Opencv— — image offset

    // define head function #ifndef PS_ALGORITHM_H_INCLUDED #define PS_ALGORITHM_H_INCLUDED #include < ...

  4. 「LuoguP3796」 【模板】AC自动机(加强版)

    题目描述 有N个由小写字母组成的模式串以及一个文本串T.每个模式串可能会在文本串中出现多次.你需要找出哪些模式串在文本串T中出现的次数最多. 输入输出格式 输入格式: 输入含多组数据. 每组数据的第一 ...

  5. 网络应用软件结构-----CS与BS结构(网络基本知识小结)

    1.网络的大致结构 2.网络编程 通过直接或间接地使用网络通讯的协议实现计算机与计算机之间的通讯.在TCP/IP协议层主要麦网络主机的定位,数据传输的路由,由IP地址可以唯一地确定Internet上的 ...

  6. ununtu 下安装 Nvidia 显卡驱动

    本人电脑硬件配置:CPU : AMD Athlon(tm) II X2 215 Processor × 2 显示卡 : GeForce 6150SE nForce 430/integrated/SSE ...

  7. 二级ul li元素动态加载click事件

    一.代码 html代码: <ul class="id1" id="id1" style="width:84%; height:75%;overf ...

  8. SetConsoleCtrlHandler() -- 设置控制台信号处理函数

    http://www.groad.net/bbs/thread-8253-1-1.html 当你在命令行里工作时,经常会输入 Ctrl-C 这个组合键以停止程序的运行.SetConsoleCtrlHa ...

  9. 标准C++中的string

    转自http://www.cnblogs.com/xFreedom/archive/2011/05/16/2048037.html 要想使用标准C++中string类,必须要包含 #include & ...

  10. 【eclipse插件开发实战】Eclipse插件开发3——OSGi、RCP

    Eclipse插件开发实战3--OSGi.RCP 一.OSGi 1. 什么是OSGi框架 OSGi(Open Service Gateway Initiative)框架是运行在JavaVM环境里的服务 ...