题目链接:点击打开链接

题意:

给定n*m的地图 a个男人 b个女人

下面n*m的方格图.表示空地 *表示障碍。

下面第一行给出中性人的坐标和移动时间

下面a行给出每个男人的坐标和移动时间

下面b行给出女人的坐标和移动时间。

移动时间是指人移动到相邻矩阵的时间(人是不能走到障碍物上的)

每个空地上恰好有一间房子(一间房子只能住一对夫妇,住了人的空地别人还是可以走过的)。

目标:使得所有人都结成夫妇且住在房子里(中性人可以和男的结成夫妇,也可以和女的结成夫妇)

所花的最大时间最小,即最后一个人住进房子的时间最小。

思路:

假设没有变性人,则这题就是一个经典建图了,

二分最大时间,然后建图即可。

设now为每个人允许运动的最大时间

男人连源点 flow = 1

男人连能走到的房子 flow = 1 (所谓能走到就是所花时间<=now)

房子连女人 flow = 1

女人连汇点 flow = 1

因为一个房子只能住一个人,所以房子拆点一下,限流为1

而对于变性人其实并不是任意匹配的,当且仅当 abs(男人数量-女人数量)=1时才能找到解,即一开始就能确定变性人的性别。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<queue>
#include<cmath>
template <class T>
inline bool rd(T &ret) {char c; int sgn;if (c = getchar(), c == EOF) return 0;while (c != '-' && (c<'0' || c>'9')) c = getchar();sgn = (c == '-') ? -1 : 1;ret = (c == '-') ? 0 : (c - '0');while (c = getchar(), c >= '0'&&c <= '9') ret = ret * 10 + (c - '0');ret *= sgn;return 1;
}
template <class T>
inline void pt(T x) {if (x <0) {putchar('-');x = -x;}if (x>9) pt(x / 10);putchar(x % 10 + '0');
}
using namespace std;
typedef long long ll;
const ll inf = 1e10;
const int N = 10019;
const int M = 10000000;
template<class T>
struct Max_Flow {int n;int Q[N], sign;int head[N], level[N], cur[N], pre[N];int nxt[M], pnt[M], E;T cap[M];void Init(int n) {this->n = n + 1;E = 0;std::fill(head, head + this->n, -1);}//有向rw 就= 0  void add(int from, int to, T c, T rw) {pnt[E] = to;cap[E] = c;nxt[E] = head[from];head[from] = E++;pnt[E] = from;cap[E] = rw;nxt[E] = head[to];head[to] = E++;}bool Bfs(int s, int t) {sign = t;std::fill(level, level + n, -1);int *front = Q, *tail = Q;*tail++ = t; level[t] = 0;while (front < tail && level[s] == -1) {int u = *front++;for (int e = head[u]; e != -1; e = nxt[e]) {if (cap[e ^ 1] > 0 && level[pnt[e]] < 0) {level[pnt[e]] = level[u] + 1;*tail++ = pnt[e];}}}return level[s] != -1;}void Push(int t, T &flow) {T mi = inf;int p = pre[t];for (int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {mi = std::min(mi, cap[p]);                                                                                                                                       }for (int p = pre[t]; p != -1; p = pre[pnt[p ^ 1]]) {cap[p] -= mi;if (!cap[p]) {sign = pnt[p ^ 1];}cap[p ^ 1] += mi;}flow += mi;}void Dfs(int u, int t, T &flow) {if (u == t) {Push(t, flow);return;}for (int &e = cur[u]; e != -1; e = nxt[e]) {if (cap[e] > 0 && level[u] - 1 == level[pnt[e]]) {pre[pnt[e]] = e;Dfs(pnt[e], t, flow);if (level[sign] > level[u]) {return;}sign = t;}}}T Dinic(int s, int t) {pre[s] = -1;T flow = 0;while (Bfs(s, t)) {std::copy(head, head + n, cur);Dfs(s, t, flow);}return flow;}
};
Max_Flow <ll>F;
struct node{int x, y; ll t;node(int a = 0, int b = 0, ll c = 0) :x(a), y(b), t(c){}
}AA[N], B[N], C;
int n, m, a, b;
char mp[24][24];
ll Dis[24][24][24][24];
int has1(int x){ return x - 1; }
int has2(int x, int y){ return a + (x - 1)*m + y - 1; }
int has3(int x, int y){ return a + n*m + (x - 1)*m + y - 1; }
int has4(int x){ return a + 2 * n*m + x - 1; }
bool ok(ll now){int from = has4(b) + 1, to = from + 1;F.Init(to+10);for (int i = 1; i <= a; i++){F.add(from, has1(i), 1, 0);for (int x = 1; x <= n; x++)for (int y = 1; y <= m; y++)if (Dis[x][y][AA[i].x][AA[i].y] < inf && Dis[x][y][AA[i].x][AA[i].y] * AA[i].t <= now)F.add(has1(i), has2(x, y), 1, 0);}for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)if (mp[i][j] == '.') F.add(has2(i, j), has3(i, j), 1, 0);for (int i = 1; i <= b; i++){F.add(has4(i), to, 1, 0);for (int x = 1; x <= n; x++)for (int y = 1; y <= m; y++)if (Dis[x][y][B[i].x][B[i].y] < inf && Dis[x][y][B[i].x][B[i].y] * B[i].t <= now)F.add(has3(x, y), has4(i), 1, 0);}return F.Dinic(from, to) == b;
}
ll solve(){if (a != b)return -1;ll ans = -1, l = 0, r = 1e18;while (l <= r){ll mid = (l + r) >> 1;if (ok(mid)){r = mid - 1;ans = mid;}elsel = mid + 1;}return ans;
}
void pre(){for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)for (int x = 1; x <= n; x++)for (int y = 1; y <= m; y++)Dis[i][j][x][y] = inf;int step[4][2] = { 0, 1, 0, -1, 1, 0, -1, 0 };for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++){if (mp[i][j] == '*')continue;Dis[i][j][i][j] = 0;for (int k = 0; k < 4; k++){int x = i + step[k][0], y = j + step[k][1];if (1 <= x && x <= n && 1 <= y&&y <= m && mp[x][y] == '.')Dis[i][j][x][y] = 1;}}for (int x1 = 1; x1 <= n; x1++)for (int y1 = 1; y1 <= m; y1++) if (mp[x1][y1] == '.')for (int x2 = 1; x2 <= n; x2++)for (int y2 = 1; y2 <= m; y2++) if (mp[x2][y2]=='.' && Dis[x2][y2][x1][y1]<inf)for (int x3 = 1; x3 <= n; x3++)for (int y3 = 1; y3 <= m; y3++) if (mp[x3][y3] == '.')Dis[x2][y2][x3][y3] = min(Dis[x2][y2][x3][y3], Dis[x2][y2][x1][y1] + Dis[x1][y1][x3][y3]);if (a>b)B[++b] = C;else AA[++a] = C;
}
void input(){rd(n); rd(m); rd(a); rd(b);for (int i = 1; i <= n; i++)scanf("%s", mp[i] + 1);rd(C.x); rd(C.y); rd(C.t);for (int i = 1; i <= a; i++) { rd(AA[i].x); rd(AA[i].y); rd(AA[i].t); }for (int i = 1; i <= b; i++) { rd(B[i].x); rd(B[i].y); rd(B[i].t); }
}int main(){input();pre();cout<<solve()<<endl;return 0;
}

Codeforces 513F1 513F2 Scaygerboss 网络流相关推荐

  1. SCAU-春季训练-不应该啊(怎么这么菜。。。)

    2021/3/14 春季训练2(难度div2d) 反思:(赛前,看什么crt,赛时满脑子都是线性方程组,....................................) 最近表现都不太好.. ...

  2. CodeForces 1517G Starry Night Camping(网络流最小割)

    CodeForces 1517G Starry Night Camping problem 洛谷链接 solution 这个平行四边形的脑洞我™真的长见识了 本题最离谱的要求就是:平行四边形的一条边平 ...

  3. Codeforces 1045. A. Last chance(网络流 + 线段树优化建边)

    题意 给你 \(n\) 个武器,\(m\) 个敌人,问你最多消灭多少个敌人,并输出方案. 总共有三种武器. SQL 火箭 - 能消灭给你集合中的一个敌人 \(\sum |S| \le 100000\) ...

  4. 网络流(最大流):CodeForces 499E Array and Operations

    You have written on a piece of paper an array of n positive integers a[1], a[2], ..., a[n] and m goo ...

  5. CodeForces 1045A. Last chance(线段树+网络流SAP)

    网络流,对三种武器分别有不同建图的方法,核心宗旨是:源点->武器->飞船->汇点. SQL rockets – every SQL rocket can destroy at mos ...

  6. Codeforces Educational Round#21 F(808F) Solution:网络流(最小割)

    题意:给出一组卡牌(100张),卡牌有三个属性值:power,c,level,其中c和level是用来限制的,power是目标值. 具体的限制规则是:只有level小于等于玩家的playerlevel ...

  7. codeforces 546 E. Soldier and Traveling(网络流+路径输出)

    题目链接:https://codeforces.com/problemset/problem/546/E 思路:很简单的建图,留个输出路径的板子 #include <cstdio> #in ...

  8. codeforces 653D D. Delivery Bears(二分+网络流)

    题目链接: D. Delivery Bears time limit per test 2 seconds memory limit per test 256 megabytes input stan ...

  9. codeforces#254DIV2解题报告

    今天简直大爆发啊... 吃了顿烧烤竟然这么管事. . . .. 本弱渣竟然做出来了3道,并且B题是我第一次在CF中用到算法..(曾经最多也就是贪心. . . ). 题目地址:codeforces#22 ...

最新文章

  1. 44岁的微软如何刷新未来?
  2. Lasso回归的坐标下降法推导
  3. 浅谈人性 - 讲讲人性丑恶的一面
  4. Redis开发运维实践问题处理只内存检查
  5. 反序列化的时候出现eof exception_FastJson序列化时候出现了$ref?还不赶紧学习下...
  6. 服务器配置 | 3306端口被占用,phpStudy无法启动Apache
  7. xcode 4 制作静态库(转)
  8. 计算机网络交换机组网及虚拟局域网实验报告,计算机网络实验报告材料(虚拟局域网).doc...
  9. 计算机操作系统-详细版-王道
  10. Oracle 官方文档在线查看Oracle函数
  11. 十大概念:每个软件工程师的必备
  12. 使用visdom三维可视化图像。
  13. python读取fits第三方库_Python读取和显示Fits文件
  14. 生活随记 - 火星梦
  15. 数据分析第二章numpy数值运算
  16. 基于SABR模型的期权波动率曲线套利策略
  17. 嵌入式开发要学什么_必备嵌入式学习路线_高手速成方法
  18. 微信小程序--云开发数据库操作之where()
  19. 启动weblogic 报错
  20. 游客不满旅游团更改路线要求退钱遭推搡骨折

热门文章

  1. 跳槽的新公司,我直接让项目的性能提升了一半
  2. 有哪些电容笔值得推荐?值得买的电容笔测评
  3. echarts的饼图制作分析
  4. 编程语言理解3-目前主流的编程语言有哪些,分别的应用场景是什么
  5. 操作系统–––成组链接法
  6. 华米手表安装第三方应用
  7. python 数据分析核心--pandas
  8. 与全球外国人即时聊天的网站
  9. 睿企管家成功入驻航天云网 助力160万云网企业用户数字化转型
  10. SEO工作前景如何?