BZOJ1001 狼抓兔子(网络流转最短路:对偶图)
题意:
给一个如图形式的\(n*m\)的方格,从左上走到右下,给出边权,问分成两块所需的最小代价。\(n,m\leq1000\)。
思路:
显然是个最小割,但是\(O(n^2m)\)的复杂度很高,虽然这道题能过。
这里介绍一种最大流改最短路的方法——对偶图。
对任意一个图我们可以变成对偶图:
如下图,每一个闭合的平面我们都给他标号,然后连接源点和汇点,把外面那个无穷大的平面分成两个平面\(s,t\)。然后开始新建边。新建边的每一条边为:把一条原来边的左右两个平面连接到一起,权值为原来的边的权值。可以得出最后的新建的边的数量和原来一样。最后跑\(s,t\)的最短路即可得出原图的最大流。

代码:
#include <map>
#include <set>
#include <queue>
#include <cmath>
#include <stack>
#include <ctime>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const int maxn = 3e6 + 5;
const int MAXM = 3e6;
const ll MOD = 1e9 + 7;
const ull seed = 131;
const int INF = 0x3f3f3f3f;
struct Edge{
int to, next;
int w;
}edge[MAXM * 2];
struct qnode{
int u;
int c;
qnode(int _u = 0, int _c = 0):u(_u), c(_c){}
bool operator < (const qnode &r) const{
return r.c < c;
}
};
int tot, head[maxn], vis[maxn];
int dis[maxn];
void addEdge(int u, int v, int w){
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
void Dijkstra(int n, int st){
memset(vis, 0, sizeof(vis));
for(int i = 0; i <= n; i++) dis[i] = INF;
priority_queue<qnode> que;
while(!que.empty()) que.pop();
dis[st] = 0;
que.push(qnode(st, 0));
qnode temp;
while(!que.empty()){
temp = que.top();
que.pop();
int u = temp.u;
if(vis[u]) continue;
vis[u] = 1;
for(int i = head[u]; i != -1; i = edge[i].next){
int v = edge[i].to;
int w = edge[i].w;
if(!vis[v] && dis[v] > dis[u] + w){
dis[v] = dis[u] + w;
que.push(qnode(v, dis[v]));
}
}
}
}
int n, m;
int getupid(int x, int y){
return (x - 1) * (m - 1) + y;
}
int getdownid(int x, int y){
return (x - 1) * (m - 1) + y + (n - 1) * (m - 1);
}
int main(){
memset(head, -1, sizeof(head));
tot = 0;
scanf("%d%d", &n, &m);
if(n == 1 || m == 1){
int ans = INF;
if(n == m) ans = 0;
if(n < m) swap(n, m);
for(int i = 1; i <= n - 1; i++){
int w;
scanf("%d", &w);
ans = min(ans, w);
}
printf("%d\n", ans);
return 0;
}
int st = 0, en = (n - 1) * (m - 1) * 2 + 1;
for(int i = 1; i <= n; i++){
for(int j = 1; j <= m - 1; j++){
int w;
scanf("%d", &w);
if(i == 1){
addEdge(st, getupid(i, j), w);
addEdge(getupid(i, j), st, w);
}
else if(i == n){
addEdge(en, getdownid(i - 1, j), w);
addEdge(getdownid(i - 1, j), en, w);
}
else{
addEdge(getupid(i, j), getdownid(i - 1, j), w);
addEdge(getdownid(i - 1, j), getupid(i, j), w);
}
}
}
for(int i = 1; i <= n - 1; i++){
for(int j = 1; j <= m; j++){
int w;
scanf("%d", &w);
if(j == 1){
addEdge(getdownid(i, j), en, w);
addEdge(en, getdownid(i, j), w);
}
else if(j == m){
addEdge(getupid(i, j - 1), st, w);
addEdge(st, getupid(i, j - 1), w);
}
else{
addEdge(getdownid(i, j), getupid(i, j - 1), w);
addEdge(getupid(i, j - 1), getdownid(i, j), w);
}
}
}
for(int i = 1; i <= n - 1; i++){
for(int j = 1; j <= m - 1; j++){
int w;
scanf("%d", &w);
addEdge(getupid(i, j), getdownid(i, j), w);
addEdge(getdownid(i, j), getupid(i, j), w);
}
}
Dijkstra(en, st);
printf("%d\n", dis[en]);
return 0;
}
BZOJ1001 狼抓兔子(网络流转最短路:对偶图)的更多相关文章
- [bzoj1001][BJOI2006]狼抓兔子——最大流转最短路,平面图
题目描述: 给定一个平面图,求最小割. 题解: 本题是一道经典题. 周冬Orz的论文是很好的研究资料. 这道题点太多,所以直接跑dinic无疑会超时. 我们观察原图,发现原图是一个平面图. 什么是平面 ...
- bzoj1001狼抓兔子 对偶图优化
bzoj1001狼抓兔子 对偶图优化 链接 https://www.lydsy.com/JudgeOnline/problem.php?id=1001 思路 菜鸡总是要填坑的! 很明显让你求网格图的最 ...
- BZOJ-1001 狼抓兔子 (最小割-最大流)平面图转对偶图+SPFA
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 14686 Solved: 3513 [Submit][ ...
- bzoj1001狼抓兔子
1001: [BeiJing2006]狼抓兔子 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你 ...
- BZOJ1001:狼抓兔子(最小割最大流+vector模板)
1001: [BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨, ...
- 【BZOJ】1001: [BeiJing2006]狼抓兔子 Dinic算法求解平面图对偶图-最小割
1001: [BeiJing2006]狼抓兔子 Description 左上角点为(1,1),右下角点为(N,M)(上图中N=4,M=5).有以下 三种类型的道路 1:(x,y)<==>( ...
- BZOJ_2001_[BeiJing2006]狼抓兔子_最小割转对偶图
BZOJ_2001_[BeiJing2006]狼抓兔子 题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 分析:思路同NOI2010海拔. ...
- 【建图+最短路】Bzoj1001 狼抓兔子
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...
- BZOJ1001 狼抓兔子(裸网络流)
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...
- BZOJ1001 狼抓兔子 平面图转对偶图 最小割
现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为 ...
随机推荐
- CMU数据库(15-445)Lab1-BufferPoolManager
0. 关于环境搭建请看 https://www.cnblogs.com/JayL-zxl/p/14307260.html 1. Task1 LRU REPLACEMENT POLICY 0. 任务描述 ...
- docker 运行时常见错误
docker 运行时常见错误 (1) Cannot connect to the Docker daemon at unix:///var/run/docker.sock. [root@localho ...
- jmeter-命令行执行及测试报告导出
问题1:GUI方式能够进行测试报告导出? 回答:目前找了很多资料,没有找到采用GUI方式测试完成,然后命令方式导出测试报告: 问题2:命令行导出测试报告的前提都有啥?---- 这里参考了老_张大大的博 ...
- Eureka详解系列(二)--如何使用Eureka(原生API,无Spring)
简介 通过上一篇博客 Eureka详解系列(一)--先谈谈负载均衡器 ,我们知道了 Eureka 是什么以及为什么要使用它,今天,我们开始研究如何使用 Eureka. 在此之前,先说明一点.网上几乎所 ...
- 让源码包apache服务被服务管理命令识别
在默认情况下,源码包服务是不能被系统的服务管理命令所识别和管理的,但是如果我们做一些设定,则也是可以让源码包服务被系统的服务管理命令所识别和管理的.不过笔者并不推荐大家这样做, 因为这会让本来区别很明 ...
- (002)每日SQL学习:删除名称重复的数据
create table A ( id VARCHAR2(36), name VARCHAR2(100), sl VARCHAR2(36) ); insert all into a (id,name) ...
- spark join 广告用户特征 与广告特征的 join 拿到训练集
spark join 广告特征做广播
- 改造xxl-job的客户端日志文件生成体系
为什么要改造XXL-JOB原有的日志文件生成体系 xxl-job原本自己的客户端日志文件生成策略是:一个日志记录就生成一个文件,也就是当数据库存在一条日志logId,对应的客户端就会生成一个文件, ...
- Nginx上安装SSL证书
准备 参考 :链接 下载的Nginx证书压缩文件解压后包含: .pem:证书文件.PEM文件的扩展名为CRT格式. .key:证书密钥文件.申请证书时如果未选择自动创建CRS,则下载的证书文件压缩包中 ...
- Spring MVC接收参数(Map,List,JSON,Date,2个Bean)(记录一次面试惨状)
题目Spring MVC 接收参数 MapListDate2个BeanJSON Spring MVC接收参数 -Map Spring MVC接收参数 -List Spring MVC接收参数 -dat ...