bzoj1001 [ICPC-Beijing 2006]狼抓兔子
我满心以为本题正解为最短路,结果到处都是最大流……
几乎所有的都写了什么“对偶图”跑最短路,但我真的不知道什么叫做对偶图
-------------------------------------------------------------------------------------------------
介绍一下本题的最短路算法叭。并不算难。主要是感性理解。
首先很容易观察出这是一个最小割,那么就是求最大流了。
但是这题的点数高达10e6,按常理来说最大流应该稳稳地TLE。但是没有T好气哦
那么想办法!
首先最小割在本题时可以这样感性理解:上图是一个你同学在钢铁厂打出来的一个铁架子。你把start处用手捏起来,end处自然垂下。用一个剪刀钳把这个铁架子拦腰剪成两半。
如果剪成好几瓣(掉下来有好几个联通块的),那么显而易见,不如剪成两半(把刚才几个剪断的地方原样拼起来变成两个联通块)。
我们把三角形看成是点,黑色的边看成是连接三角形的边,那么剪成两半的意思是……在三角形点的图上找一条从左下到右上的最短路径!沿着这条路径剪开就行了。
但是这题的点数高达10e6,按常理来说SPFA应该稳稳地TLE。但是没有T好气哦
那就堆优化dijkstra。
这个加边超烦的。但思路清晰的话就没什么问题。记得在左下空白处设一个源点,右上角设一个汇点。源点连接所有邻接它的左边的、下边的三角形点,汇点连接所有邻接它的右边的、上边的三角形点。
#include <cstdio>
#include <queue>
using namespace std;
const int N=,S=N*N*+,inf=(<<)-;
int n,m,a[N][N],b[N][N],c[N][N],d[S],id[N][N],ss,tt,h[S],v[S],nx[S],w[S],eg=;
bool vis[S]={};
struct info
{
int x,w;
}data;
inline bool operator<(const info &a,const info &b)
{
return a.w>b.w;
}
priority_queue<struct info> pq;
inline void egadd(int uu,int vv,int ww)
{
nx[++eg]=h[uu];h[uu]=eg;
v[eg]=vv;w[eg]=ww;
}
void rd(int &s)
{
s=;char c=getchar();
while (c<) c=getchar();
while (c>=) s=(s<<)+(s<<)+(c^),c=getchar();
}
int main()
{
scanf("%d%d",&n,&m);
for (int i=;i<=n;i++)
for (int j=;j<=m-;j++)
rd(a[i][j]);
for (int i=;i<=n-;i++)
for (int j=;j<=m;j++)
rd(b[i][j]);
for (int i=;i<=n-;i++)
for (int j=;j<=m-;j++)
rd(c[i][j]);
n--;m--;
if (!n)
{
int res=inf;
for (int i=;i<=m;i++)
if (a[][i]<res)
res=a[][i];
printf("%d",res);
return ;
}
if (!m)
{
int res=inf;
for (int i=;i<=n;i++)
if (b[i][]<res)
res=b[i][];
printf("%d",res);
return ;
}
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
id[i][j]=(i-)**m+j;
ss=n**m+;tt=ss+;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++)
{
egadd(id[i][j],id[i][j]+m,c[i][j]);
egadd(id[i][j]+m,id[i][j],c[i][j]);
}
for (int i=;i<=n;i++)
for (int j=;j<=m-;j++)
{
egadd(id[i][j],id[i][j+]+m,b[i][j+]);
egadd(id[i][j+]+m,id[i][j],b[i][j+]);
}
for (int i=;i<=n-;i++)
for (int j=;j<=m;j++)
{
egadd(id[i][j]+m,id[i+][j],a[i+][j]);
egadd(id[i+][j],id[i][j]+m,a[i+][j]);
}
for (int i=;i<=m;i++)
{
egadd(id[][i],tt,a[][i]);
egadd(ss,id[n][i]+m,a[n+][i]);
}
for (int i=;i<=n;i++)
{
egadd(ss,id[i][]+m,b[i][]);
egadd(id[i][m],tt,b[i][m+]);
}
for (int i=;i<=tt;i++)
d[i]=inf;
d[ss]=;
pq.push((info){ss,});
while (!pq.empty())
{
while (!pq.empty() && vis[pq.top().x])
pq.pop();
if (pq.empty()) break;
data=pq.top();
pq.pop();
int x=data.x,ww=data.w;
printf("%d %d\n",x,ww);
vis[x]=true;
for (int i=h[x];i;i=nx[i])
if (!vis[v[i]] && d[v[i]]>ww+w[i])
{
d[v[i]]=ww+w[i];
pq.push((info){v[i],d[v[i]]});
printf("Add:%d %d\n",v[i],d[v[i]]);
}
}
printf("%d",d[tt]);
return ;
}
bzoj1001 [ICPC-Beijing 2006]狼抓兔子的更多相关文章
- P4001 [ICPC-Beijing 2006]狼抓兔子
题目地址:P4001 [ICPC-Beijing 2006]狼抓兔子 平面图 边与边只在顶点相交的图. 对偶图 对于一个平面图,都有其对应的对偶图. 平面图被划分出的每一个区域当作对偶图的一个点: 平 ...
- 2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割)
2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割) https://www.luogu.com.cn/problem/P4001 题意: 把图分成两部分需要的最 ...
- 洛谷 P4001 [ICPC-Beijing 2006]狼抓兔子
题目描述 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: ...
- BZOJ1001/LG4001 「ICPC Beijing2006」狼抓兔子 平面图最小割转对偶图最短路
问题描述 BZOJ1001 LG4001 题解 平面图最小割=对偶图最短路 假设起点和终点间有和其他边都不相交的一条虚边. 如图,平面图的若干条边将一个平面划分为若干个图形,每个图形就是对偶图中的一个 ...
- 解题:BJOI 2006 狼抓兔子
题面 可以看出来是最小割,然后你就去求最大流了 这么大的范围就是让你用网络流卡的?咋想的啊=.=??? 建议还是老老实实用 平面图最小割等于其对偶图最短路 这个东西来做吧,虽然这个东西跑的也挺慢的,最 ...
- ICPC-Beijing 2006 狼抓兔子
题目描述 题解: 裸的最小割. 但是最大流跑不过去怎么办? 转变一下,既然最大流是一条左下<->右上的通路,我们可以把图划分为若干区域, 最后找左下到右上的最短路就行了. 代码: #inc ...
- [BZOJ 2006] 狼抓兔子
[题目链接] https://www.lydsy.com/JudgeOnline/problem.php?id=1001 [算法] 最小割 [代码] #include<bits/stdc++.h ...
- 【洛谷4001】 [ICPC-Beijing 2006]狼抓兔子(最小割)
传送门 洛谷 Solution 直接跑最小割板子就好了. 代码实现 #include<stdio.h> #include<stdlib.h> #include<strin ...
- 洛谷$P4001\ [ICPC-Beijing 2006]$狼抓兔子 网络流+对偶图
正解:网络流+对偶图 解题报告: 传送门! $umm$日常看不懂题系列了$kk$.其实就是说,给定一个$n\cdot n$的网格图,求最小割$QwQ$ 然后网格图的话显然是个平面图,又看到数据范围$n ...
随机推荐
- Code First 延迟装入特性
使用ORM框架,基本上都会添加“延迟装入”的特性支持,当使用Entity Framwork 的objectContext与DbContext操作数据时,默认都使用“延迟装入”,也就是当我们在应用程序里 ...
- BZOJ 2301 莫比乌斯反演入门
2301: [HAOI2011]Problem b Description 对于给出的n个询问,每次求有多少个数对(x,y),满足a≤x≤b,c≤y≤d,且gcd(x,y) = k,gcd(x,y)函 ...
- Android动画效果 translate、scale、alpha、rotate 切换Activity动画 控件位置调整
2011.10.28注:如果需要控件停在动画后的位置,需要设置android:fillAfter属性为true,在set节点中.默认在动画结束后回到动画前位置.设置android:fillAfter后 ...
- SCP-bzoj-1085
项目编号:bzoj-1085 项目等级:Safe 项目描述: 戳这里 特殊收容措施: A*(上下界剪枝). 答案上界:15. 答案下界:当前步数+当前状态剩余步数估价. 这里我们简单地设计估价函数为当 ...
- Comet OJ 三元组 推导+两个指针+分类讨论
题目:https://www.cometoj.com/contest/59/problem/F?problem_id=2681 题意:给你n个三元组 ai,bi,ci,如果某一对三元组满足 2* ...
- 探索Redis设计与实现8:连接底层与表面的数据结构robj
本文转自互联网 本系列文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查看 https://github.com/h2pl/Java-Tutorial ...
- AndroidManifest.xml配置文件详解(转)
转载博客:http://blog.csdn.net/shagoo/article/details/7485958# AndroidManifest.xml配置文件对于Android应用开发来说是非常重 ...
- (54) C# 调用 kernel32.dll
https://www.cnblogs.com/cwy173/archive/2010/10/02/1841321.html Kernel32 API AddAtom 向本地原子表添加一个字符串 Al ...
- java == 和equals()
== == 是运算符 :可以使用在基本数据类型变量和引用数据类型变量当中 : 如果比较的是基本数据类型变量,比较两个变量保存的数据是否相等(不一定类型相同) 如果比较的是引用数据类型变量, 比较两个对 ...
- EOJ 1127. 多边形面积(计算几何)
题目链接:1127. 多边形面积(计算几何) 题意 按逆时针顺序给出 \(n\) 个点的坐标,求这些点围成的多边形的面积. 思路 选择多边形上的一个点,然后每次枚举之后的两个点,计算叉积,注意要保留符 ...