Luogu 4001 [BJOI2006]狼抓兔子
BZOJ 1001……
并不会这个trick,所以笔记要详细一点。
前置知识 : 平面图转对偶图 传送门
听说直接$Dinic$就好了,还跑得比正解快……
首先我们按照平面图的定义,把网格图中所有的平面以及另加的起点和终点在新图中标号,一共有$(n - 1) * (m - 1) * 2 + 2$个点,标完样例之后大概是这样子的:

然后我们接着按照定义,把有相邻的边的点连上双向边,对于那些在边界上的边,我们分别选择和$st$和$ed$连边,具体来说是这样的:

红色的边和$st$连边,蓝色的边和$ed$连边,其他黑色的边和它相邻的两个联通块连边。
注意$n == 1$或者$m == 1$的时候其实是一条链的情况,只要把最小的边鸽掉就好了,这时候所有的边都是要从$st$出发连到$ed$的,但是我的写法会挂掉,所以需要拎出来特判一下。
容易发现这样子构图之后从$st$到$ed$的每一条路都对应了原图中左上角到右下角的一个鸽,这样子我们求一个最小鸽就变成了一个最短路,就能方便地跑过去了。
要注意一个细节就是说$st$和$ed$必须放在左下角和右上角(可以对调),因为我们在原图中是要从左上角到右下角求一个最小鸽,要不然就不代表从左上角到右下角的一个最小鸽了吧。
连完边之后的效果图大概是这个大神博客里面的样子。 戳这里
时间复杂度$O(nmlognm)$。
Code:
#include <cstdio>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
typedef pair <int, int> pin; const int N = 2e6 + ;
const int M = 6e6 + ; int n, m, tot = , head[N], dis[N];
bool vis[N]; struct Edge {
int to, nxt, val;
} e[M]; inline void add(int from, int to, int val) {
e[++tot].to = to;
e[tot].val = val;
e[tot].nxt = head[from];
head[from] = tot;
} inline void addEdge(int x, int y, int v) {
add(x, y, v), add(y, x, v);
} inline void read(int &X) {
X = ; char ch = ; int op = ;
for(; ch > '' || ch < ''; ch = getchar())
if(ch == '-') op = -;
for(; ch >= '' && ch <= ''; ch = getchar())
X = (X << ) + (X << ) + ch - ;
X *= op;
} priority_queue <pin> Q;
inline void dij(int st) {
memset(dis, 0x3f, sizeof(dis));
memset(vis, , sizeof(vis));
Q.push(pin(dis[st] = , st));
for(; !Q.empty(); ) {
int x = Q.top().second; Q.pop();
if(vis[x]) continue;
vis[x] = ;
for(int i = head[x]; i; i = e[i].nxt) {
int y = e[i].to;
if(dis[y] > dis[x] + e[i].val) {
dis[y] = dis[x] + e[i].val;
Q.push(pin(-dis[y], y));
}
}
}
} int main() {
// freopen("5.in", "r", stdin); read(n), read(m);
int st = (n - ) * (m - ) * + , ed = st + ;
if(n == || m == ) {
for(int i = ; i <= n; i++)
for(int j = ; j < m; j++) {
int val; read(val);
addEdge(st, ed, val);
}
for(int i = ; i < n; i++)
for(int j = ; j <= m; j++) {
int val; read(val);
addEdge(st, ed, val);
}
for(int i = ; i < n; i++)
for(int j = ; j < m; j++) {
int val; read(val);
addEdge(st, ed, val);
}
} else {
for(int i = ; i <= n; i++)
for(int j = ; j < m; j++) {
int val; read(val);
if(i == ) addEdge(ed, * ((i - ) * (m - ) + j), val);
if(i == n) addEdge(st, * ((i - ) * (m - ) + j) - , val);
if(i != && i != n) addEdge( * ((i - ) * (m - ) + j), * ((i - ) * (m - ) + j) - , val);
}
for(int i = ; i < n; i++)
for(int j = ; j <= m; j++) {
int val; read(val);
if(j == ) addEdge(st, * ((i - ) * (m - ) + j) - , val);
if(j == m) addEdge(ed, * ((i - ) * (m - ) + j - ), val);
if(j != && j != m) addEdge( * ((i - ) * (m - ) + j) - , * ((i - ) * (m - ) + j) - , val);
}
for(int i = ; i < n; i++)
for(int j = ; j < m; j++) {
int val; read(val);
addEdge( * ((i - ) * (m - ) + j) - , * ((i - ) * (m - ) + j), val);
}
} dij(st); printf("%d\n", dis[ed]);
return ;
}
Luogu 4001 [BJOI2006]狼抓兔子的更多相关文章
- BZOJ1001 洛谷4001 [BJOI2006]狼抓兔子 题解
题目 这个题目有多种解法,这个题也是一个比较经典的题了,正是因为他的多样的做法,这个题主要难在建图和优化,因为这是一个网格图,所以spfa肯定过不去,所以用最短路解法的话,只能用dij,而网络流也是要 ...
- BZOJ1001或洛谷4001 [BJOI2006]狼抓兔子
BZOJ原题链接 洛谷原题链接 显然就是求最小割. 而对于一个平面图有结论,最大流=最小割=对偶图最短路. 所以这题可用最大流或是转换为对偶图求最短路,这里我是用的对偶图. 虽然理论上按上界算,这题\ ...
- P4001 [BJOI2006]狼抓兔子(对偶图)
P4001 [BJOI2006]狼抓兔子 最短路+对偶图 看这题最容易想到的就是网络流.Dinic可以过,据说还跑得比正解快. 如果不写网络流,那么需要知道2个前置知识:平面图和对偶图(右转baidu ...
- BJOI2006狼抓兔子
1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MBSubmit: 9967 Solved: 2267[Submit][S ...
- 752. [BJOI2006] 狼抓兔子
★★★ 输入文件:bjrabbit.in 输出文件:bjrabbit.out 简单对比时间限制:1 s 内存限制:162 MB Description Source: Beijin ...
- [BJOI2006]狼抓兔子
题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- 1001. [BJOI2006]狼抓兔子【最小割】
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...
- BZOJ1001 BJOI2006 狼抓兔子
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个 ...
- [BJOI2006]狼抓兔子(网络流)
题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
随机推荐
- XML的语法
XML的语法 文档声明: 写法 <?xml version="1.0" ?> 文档声明必须出现在xml文件的第一行和第一列的位置 属性: version="1 ...
- UVA 10417 Gift Exchanging
#include <iostream> #include <cstring> #include <stdio.h> #include <math.h> ...
- LeetCode LFU Cache
原题链接在这里:https://leetcode.com/problems/lfu-cache/?tab=Description 题目: Design and implement a data str ...
- vue-router导航守卫
导航守卫 译者注 “导航”表示路由正在发生改变. 正如其名,vue-router 提供的导航守卫主要用来通过跳转或取消的方式守卫导航.有多种机会植入路由导航过程中:全局的, 单个路由独享的, 或者组件 ...
- bzoj 3907 网格 bzoj2822 [AHOI2012]树屋阶梯——卡特兰数(阶乘高精度模板)
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3907 https://www.lydsy.com/JudgeOnline/problem.p ...
- HDU4825(字典树+贪心)
Xor Sum Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 132768/132768 K (Java/Others)Total S ...
- hibernate中mysql数据交互中文乱码问题
来源于"http://www.cnblogs.com/jiafuwei/p/4423101.html"; 修改hibernate的配置文件hibernate.cfg.xml,在配置 ...
- 一些js和JQuery的方法
取值填值: js: get-- innerText, innerHTML, value; set-- innerText=?, innerHTML=?, value=?; JQuery: get-- ...
- ARRINC424—MORA(GRID)格式
每一整数经.纬度为一格,每格MORA值3位数字,表示百英尺.无法获知MORA值得网格一UNK表示. 经纬网格起始点坐标,每个网格从左下角开始计数,每经纬度一度切分一个网格.每行数据代表某一维度上往东或 ...
- CSS3 高级属性
尽管现代浏览器已经支持了众多的CSS3属性,但是大部分设计师和开发人员貌似依然在关注于一些很“主流”的属性,如border-radius.box-shadow或者transform等.它们有良好的文档 ...