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 编程团体赛的规则为:每个参赛队由若 ...
随机推荐
- 网页上传FLV视频文件
上传 flv格式文件一致提示文件类型不允许,是因为CI中的配置文件没有支持这个格式 在 application/config/mimes.php中加入 'flv' => array('video ...
- 英语发音规则---s发/s/的读音规则
英语发音规则---s发/s/的读音规则 一.总结 一句话总结:字母s的读音有/s/./z/./ʃ/./{/这几种,下面主要讲讲发/s/音的几条规则. 字母s的读音有/s/./z/./ʃ/./{/这几种 ...
- linux应用之基本命令
linux操作系统的应用层可以细分为两层:1.系统服务层(包括GUI shell.CUI shell.cron.ftp.远程登录openssh等由init调用的服务)2.系统命令和用户应用. linu ...
- C++软件工程师,你该会什么?
请尊重原创: 转载注明来源 原创在这里哦 C语言广泛用于基础软件.桌面系统.网络通信.音频视频.游戏娱乐等诸多领域.是世界上使用最广泛的编程语言之一.随着物联网技术的发展,C/C++技术在3G网络 ...
- certificate unknown(46) - 中间证书问题排查
因为腾讯云的网站备案迟迟没有批下来,因此使用了朋友在阿里云的域名yk,我则申请了一台阿里云服务器,并将域名解析映射至该服务器.SSL证书则是在腾讯云上申请的,使用了Apache文件夹中的文件,放置在c ...
- hdu-5670 Machine(水题附上java代码)
题目链接: Machine Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描 ...
- Android Studio 生成APK出现的「前言不允许有内容」错误
Build-Generate Signed APK的时候发现提示「前言不允许有内容」.发现提示的是Android.mk.xxxjni.c存在问题. 解决方法是,把/main/res中的,包括/jni目 ...
- bzoj 3481 DZY Loves Math III——反演+rho分解质因数
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3481 推推式子发现:令Q=gcd(P,Q),ans=Σ(d|Q) d*phi(P/d).把 ...
- C# ActiveX 中static变量缓存的问题
最近在忙活一个绘图程序,按照要求需要以ActiveX的方式发布在网站中,这个绘图程序的大概功能就是从数据库获取数据,成图.发布后用户反映,数据变化后,图形没有发生变化,好像有缓存,如果把浏览器全部关闭 ...
- 【原】Cache Buffer Chain 第四篇
作者:david_zhang@sh [转载时请以超链接形式标明文章] 链接:http://www.cnblogs.com/david-zhang-index/p/3873357.html [测试1]低 ...