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 ...
随机推荐
- C++11新特性之 Move semantics(移动语义)
https://blog.csdn.net/wangshubo1989/article/details/49748703 这篇讲到了vector的push_back的两种重载版本,左值版本和右值版本.
- parse_str()函数怎么用?
php parse_str()函数 语法 parse_str()函数怎么用? php parse_str()函数表示将字符串解析成多个变量,语法是parse_str(string,array),如果未 ...
- C# 语法特性
C# 2.0 1.泛型(Generics). 2.泛型方法.泛型委托.泛型接口. 3.泛型约束(constraints). 4.部分类(partial). 5.匿名方法. C#3.0/C#3.5 1. ...
- DBA-io
- 建站手册-浏览器信息:Netscape 浏览器
ylbtech-建站手册-浏览器信息:Netscape 浏览器 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_netscape.asp ...
- 90、Tensorflow实现分布式学习,多台电脑,多个GPU 异步试学习
''' Created on 2017年5月28日 @author: weizhen ''' import time import tensorflow as tf from tensorflow.e ...
- shell编程:函数的返回值
函数的返回值两种形式 return 0-255 0表示成功,1-255表示失败-------通常用于判断 echo 返回一个字符串------------通常用于返回一个执行的结果 return.sh ...
- shell-#!
当shell执行一个程序时,会要求UNIX内核启动一个新的进程,以便在该进程里执行所指定的程序. 当系统只有一个shell时,退回到/bin/sh 的机制非常方便,但现行的UNIX系统都会拥有好几个s ...
- linux Jenkins搭建
安装jdk 下载jdk 解压 jdk1.8 vim /etc/profile export JAVA_HOME=/usr/local/java/jdk1.8.0_111export CLASSPA ...
- poi解析word文档转换成html(包括图片解析)
需求:将本地上传的word文档解析并放入数据库中 代码: import java.io.ByteArrayOutputStream;import java.io.File;import java.io ...