https://ac.nowcoder.com/acm/contest/878/B

这个题目是一个网络流,但是建图却没有那么好建,首先我们都会把每一个人与源点相连,每一个洞口和汇点相连。

然后人和洞口相连,这个是基本思路,但是呢,这个题目因为限制了出洞口的人数,所以这个时候要将每一个洞口的每一个时刻和下一个时刻相连。

所以这个题目的建图,人和源点相连,容量为1,费用为0,人与同一时刻的洞口相连,容量为1,费用为他们之间的距离,

每一个洞口和下一时刻的这个洞口相连,容易为inf,费用为1,每一个洞口和汇点相连,容量为1,费用为0.

这个需要注意的地方:

1.人与同一时刻的洞口相连

2.就是注意这个时间最长,最长应该是n+m+k,因为一个人走到一个地方的最远距离是n+m,然后又有k个人

这个确实很难考虑,我还没有想的很清楚。

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <iostream>
#include <vector>
#include <algorithm>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int INF = 0x3f3f3f3f;
const int maxn = 1e5+;
struct edge
{
int u, v, c, f, cost;
edge(int u, int v, int c, int f, int cost) :u(u), v(v), c(c), f(f), cost(cost) {}
};
vector<edge>e;
vector<int>G[maxn];
int a[maxn];//找增广路每个点的水流量
int p[maxn];//每次找增广路反向记录路径
int d[maxn];//SPFA算法的最短路
int inq[maxn];//SPFA算法是否在队列中
void init(int n)
{
for (int i = ; i <= n; i++)G[i].clear();
e.clear();
}
void addedge(int u, int v, int c, int cost)
{
e.push_back(edge(u, v, c, , cost));
e.push_back(edge(v, u, , , -cost));
int m = e.size();
G[u].push_back(m - );
G[v].push_back(m - );
}
bool bellman(int s, int t, int& flow, long long & cost)
{
memset(d, inf, sizeof(d));
memset(inq, , sizeof(inq));
d[s] = ; inq[s] = ;//源点s的距离设为0,标记入队
p[s] = ; a[s] = INF;//源点流量为INF(和之前的最大流算法是一样的) queue<int>q;//Bellman算法和增广路算法同步进行,沿着最短路拓展增广路,得出的解一定是最小费用最大流
q.push(s);
while (!q.empty())
{
int u = q.front();
q.pop();
inq[u] = ;//入队列标记删除
for (int i = ; i < G[u].size(); i++)
{
edge & now = e[G[u][i]];
int v = now.v;
if (now.c > now.f && d[v] > d[u] + now.cost)
//now.c > now.f表示这条路还未流满(和最大流一样)
//d[v] > d[u] + e.cost Bellman 算法中边的松弛
{
d[v] = d[u] + now.cost;//Bellman 算法边的松弛
p[v] = G[u][i];//反向记录边的编号
a[v] = min(a[u], now.c - now.f);//到达v点的水量取决于边剩余的容量和u点的水量
if (!inq[v]) { q.push(v); inq[v] = ; }//Bellman 算法入队
}
}
}
if (d[t] == INF)return false;//找不到增广路
flow += a[t];//最大流的值,此函数引用flow这个值,最后可以直接求出flow
cost += (long long)d[t] * (long long)a[t];//距离乘上到达汇点的流量就是费用
for (int u = t; u != s; u = e[p[u]].u)//逆向存边
{
e[p[u]].f += a[t];//正向边加上流量
e[p[u] ^ ].f -= a[t];//反向边减去流量 (和增广路算法一样)
}
return true;
}
int MincostMaxflow(int s, int t, long long & cost)
{
cost = ;
int flow = ;
while (bellman(s, t, flow, cost));//由于Bellman函数用的是引用,所以只要一直调用就可以求出flow和cost
return flow;//返回最大流,cost引用可以直接返回最小费用
}
char mp[][];
int pos[][];
int main()
{
int n, m, k, cnt = ;
scanf("%d %d %d", &n, &m, &k);
for (int i = ; i <= n; i++)
{
scanf("%s", mp[i] + );
for (int j = ; j <= m; j++)
{
if (mp[i][j] == '')
{
pos[++cnt][] = i;
pos[cnt][] = j;
}
}
}
int sum = n + m + k;
int s = , t = k + cnt * sum + ;
for (int i = ; i <= cnt; i++)
{
for (int j = ; j <= sum; j++)
{
int tmp = k + (i - )*sum + j;
addedge(tmp, t, , );
if (j != sum) addedge(tmp, tmp + , inf, );
}
}
for (int i = ; i <= k; i++)
{
int x, y, w;
scanf("%d%d%d", &x, &y, &w);
addedge(s, i, , );
for (int j = ; j <= cnt; j++)
{
int dis = abs(pos[j][] - x) + abs(pos[j][] - y);
addedge(i, k + (j - )*sum + dis, , dis);
}
}
ll cost = ;
int ans = MincostMaxflow(s, t, cost);
printf("%lld\n", cost);
return ;
}

2019国防科大校赛 B Escape LouvreⅡ的更多相关文章

  1. 2019浙师大校赛(浙大命题)(upc复现赛)总结

    2019浙师大校赛(浙大命题)(upc复现赛)总结 早上九点开始.起得迟了,吃了早饭慌慌张张跑过去,刚到比赛就开始了. 开始分别从前往后和从后往前看题,一开始A题,第一发WA,第二次读题发现漏看了还有 ...

  2. 2019 ICPC 南昌网络赛

    2019 ICPC 南昌网络赛 比赛时间:2019.9.8 比赛链接:The 2019 Asia Nanchang First Round Online Programming Contest 总结 ...

  3. 2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem

    2019~2020icpc亚洲区域赛徐州站H. Yuuki and a problem 题意: 给定一个长度为\(n\)的序列,有两种操作: 1:单点修改. 2:查询区间\([L,R]\)范围内所有子 ...

  4. 2019 ICPC 上海区域赛总结

    2019上海区域赛现场赛总结 补题情况(以下通过率为牛客提交): 题号 标题 已通过代码 通过率 我的状态 A Mr. Panda and Dominoes 点击查看 5/29 未通过 B Prefi ...

  5. 计蒜客 41391.query-二维偏序+树状数组(预处理出来满足情况的gcd) (The Preliminary Contest for ICPC Asia Xuzhou 2019 I.) 2019年徐州网络赛)

    query Given a permutation pp of length nn, you are asked to answer mm queries, each query can be rep ...

  6. 2017河工大校赛补题CGH and 赛后小结

    网页设计课上实在无聊,便开始补题,发现比赛时候僵着的东西突然相通了不少 首先,"追妹"这题,两个队友讨论半天,分好多种情况最后放弃(可是我连题目都没看啊),今天看了之后试试是不是直 ...

  7. 2019 蓝桥杯省赛 A 组模拟赛(一)-修建公路

    题目: 蒜头国有 nn 座城市,编号分别为 0,1,2,3,...,n-1.编号为 x 和 y 的两座城市之间如果要修高速公路,必须花费 x|y 个金币,其中|表示二进制按位或. 吝啬的国王想要花最少 ...

  8. POJ-2796 & 2019南昌邀请赛网络赛 I. 区间最大min*sum

    http://poj.org/problem?id=2796 https://nanti.jisuanke.com/t/38228 背景 给定一个序列,对于任意区间,min表示区间中最小的数,sum表 ...

  9. squee_spoon and his Cube VI---郑大校赛(求最长子串)

    市面上最常见的魔方,是三阶魔方,英文名为Rubik's Cube,以魔方的发明者鲁比克教授的名字命名.另外,二阶魔方叫Pocket Cube,它只有2*2*2个角块,通常也就比较小:四阶魔方叫Reve ...

随机推荐

  1. 【python实现卷积神经网络】padding2D层实现

    代码来源:https://github.com/eriklindernoren/ML-From-Scratch 卷积神经网络中卷积层Conv2D(带stride.padding)的具体实现:https ...

  2. Redis linux 下安装

    Redis linux 下安装 下载Redis安装包,可以从Redis中文网站中下载 下载地址:http://www.redis.cn/download.html Redis4.0 稳定版本 使用&l ...

  3. IdentityServer4 QuckStart 授权与自定义Claims

    最近在折腾IdentityServer4,为了简单,直接使用了官方给的QuickStart示例项目作为基础进行搭建.有一说一,为了保护一个API,感觉花费的时间比写一个API还要多. 本文基于ASP. ...

  4. 定位new表达式与显式调用析构函数

    C++的核心理念之一是RAII,Resource Acquisition Is Initialization,资源获取即初始化.资源有很多种,内存.互斥锁.文件.套接字等:RAII可以用来实现一种与作 ...

  5. JMeter在Mac下的安装

    其实不论操作系统是Windows.Unix(如Mac OS).Linux(如Ubuntu)等,JMeter所需要的基础环境配置都是类似的,本文介绍JMeter for MAC的安装与环境配置. JMe ...

  6. 【错误】python百分号冲突not enough arguments for format string

    query = "SELECT * FROM devices WHERE devices.`id` LIKE '%{}%'".format("f2333") d ...

  7. 手写一个简单的HashMap

    HashMap简介 HashMap是Java中一中非常常用的数据结构,也基本是面试中的"必考题".它实现了基于"K-V"形式的键值对的高效存取.JDK1.7之前 ...

  8. pytorch seq2seq模型训练测试

    num_sequence.py """ 数字序列化方法 """ class NumSequence: """ ...

  9. <algorithm>中sort()函数的用法

    先说一下,本篇文章我没有讲sort()实现排序的原理,我写在另一篇文章中了,如果想了解的话,可以看一下,附上链接:https://www.cnblogs.com/buanxu/p/12772700.h ...

  10. 安装 wbemcli

    安装环境        建立自己的目录后,             wget http://vault.centos.org/6.0/os/x86_64/Packages/sblim-wbemcli- ...