BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)
想一下能猜出,最优解中海拔只有0和1,且海拔相同的点都在且只在1个连通块中。
这就是个平面图最小割。也可以转必须转对偶图最短路,不然只能T到90分了。。边的方向看着定就行。
不能忽略回去的边,因为最小割的形状可能很奇怪。
//16232kb 456ms
//平面图点数就是(n-1)^2了。但是边数不是4(n-1)^2,是4n(n-1)!。。
#include <queue>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 300000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define mp std::make_pair
#define pr std::pair<LL,int>
#define ID(x,y) ((x-1)*nn+y)
typedef long long LL;
const int N=500*500+5,M=4*500*501+5;
int n,nn,Enum,H[N],nxt[M],to[M],len[M];
bool vis[N];
LL dis[N];
std::priority_queue<pr> q;
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
#define AddEdge(u,v) to[++Enum]=v,nxt[Enum]=H[u],H[u]=Enum,len[Enum]=read()
LL Dijkstra(int S,int T)
{
memset(dis,0x3f,sizeof dis);
dis[S]=0, q.push(mp(0,S));
while(!q.empty())
{
int x=q.top().second; q.pop();
if(vis[x]) continue;
vis[x]=1;
for(int i=H[x]; i; i=nxt[i])
if(dis[to[i]]>dis[x]+len[i])
q.push(mp(-(dis[to[i]]=dis[x]+len[i]),to[i]));
}
return dis[T];
}
int main()
{
n=read()+1, nn=n-1; int S=0, T=nn*nn+1;
for(int j=1; j<n; ++j) AddEdge(S,ID(1,j));//i==1
for(int i=2; i<n; ++i)
for(int j=1; j<n; ++j) AddEdge(ID(i-1,j),ID(i,j));
for(int j=1; j<n; ++j) AddEdge(ID(nn,j),T);//i==n
for(int i=1; i<n; ++i)
{
AddEdge(ID(i,1),T);//j==1
for(int j=2; j<n; ++j) AddEdge(ID(i,j),ID(i,j-1));
AddEdge(S,ID(i,nn));//j==n
}
for(int j=1; j<n; ++j) AddEdge(ID(1,j),S);
for(int i=2; i<n; ++i)
for(int j=1; j<n; ++j) AddEdge(ID(i,j),ID(i-1,j));
for(int j=1; j<n; ++j) AddEdge(T,ID(nn,j));
for(int i=1; i<n; ++i)
{
AddEdge(T,ID(i,1));
for(int j=2; j<n; ++j) AddEdge(ID(i,j-1),ID(i,j));
AddEdge(ID(i,nn),S);
}
printf("%lld\n",Dijkstra(S,T));
return 0;
}
90分(洛谷)网络流:
/*
还是建反向边吧,虽然会有一条反向边,但是很难对应上去。。
注意n要加1,即点数是501*501=251001而不是250000。。够坑(也就坑我这种卡的了)。
*/
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define MAXIN 300000
//#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
#define ID(x,y) ((x-1)*n+y)
const int N=501*501+5/*>250005!*/,M=N<<3,INF=0x3f3f3f3f;
int n,src,des,Enum,H[N],cur[N],nxt[M],fr[M],to[M],cap[M],lev[N],pre[N],num[N];
char IN[MAXIN],*SS=IN,*TT=IN;
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int w,int u,int v)
{
to[++Enum]=v, fr[Enum]=u, nxt[Enum]=H[u], H[u]=Enum, cap[Enum]=w;
to[++Enum]=u, fr[Enum]=v, nxt[Enum]=H[v], H[v]=Enum, cap[Enum]=0;
}
bool BFS()
{
static int q[N];
for(int i=src; i<des; ++i) lev[i]=des+1;
int h=0,t=1; q[0]=des, lev[des]=0;
while(h<t)
{
int x=q[h++];
for(int i=H[x]; i; i=nxt[i])
if(lev[to[i]]==des+1 && cap[i^1])
lev[to[i]]=lev[x]+1, q[t++]=to[i];
}
return lev[src]<=des;
}
int Augment()
{
int mn=INF;
for(int i=des; i!=src; i=fr[pre[i]])
mn=std::min(mn,cap[pre[i]]);
for(int i=des; i!=src; i=fr[pre[i]])
cap[pre[i]]-=mn, cap[pre[i]^1]+=mn;
return mn;
}
long long ISAP()
{
if(!BFS()) return 0;
for(int i=src; i<=des; ++i) ++num[lev[i]],cur[i]=H[i];
int x=src; long long res=0;
while(lev[src]<=des)
{
if(x==des) x=src,res+=Augment();
bool can=0;
for(int i=cur[x]; i; i=nxt[i])
if(lev[to[i]]==lev[x]-1 && cap[i])
{
can=1, cur[x]=i, pre[x=to[i]]=i;
break;
}
if(!can)
{
int mn=des;
for(int i=H[x]; i; i=nxt[i])
if(cap[i]) mn=std::min(mn,lev[to[i]]);
if(!--num[lev[x]]) break;
++num[lev[x]=mn+1], cur[x]=H[x];
if(x!=src) x=fr[pre[x]];
}
}
return res;
}
int main()
{
n=read()+1, Enum=1, src=1, des=n*n;
for(int i=1; i<=n; ++i)
for(int j=1; j<n; ++j) AddEdge(read(),ID(i,j),ID(i,j+1));
for(int i=1; i<n; ++i)
for(int j=1; j<=n; ++j) AddEdge(read(),ID(i,j),ID(i+1,j));
for(int i=1; i<=n; ++i)
for(int j=1; j<n; ++j) AddEdge(read(),ID(i,j+1),ID(i,j));
for(int i=1; i<n; ++i)
for(int j=1; j<=n; ++j) AddEdge(read(),ID(i+1,j),ID(i,j));
printf("%lld\n",ISAP());
return 0;
}
BZOJ.2007.[NOI2010]海拔(最小割 对偶图最短路)的更多相关文章
- bzoj 2007 [Noi2010]海拔——最小割转最短路
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2007 一个点的高度一定不是0就是1.答案一定形如一个左上角的连通块全是0的点.一个右下角的连 ...
- 【bzoj2007】[Noi2010]海拔 最小割+对偶图+最短路
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个交 ...
- [NOI2010]海拔——最小割+对偶图
题目链接 SOLUTION 想一下最优情况下肯定让平路或下坡尽量多,于是不难想到这样构图:包括左上角的一部分全部为\(0\),包括右下角的一部分全部为\(1\),于是现在问题转化为求那个分界线是什么. ...
- BZOJ 2007: [Noi2010]海拔
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 2410 Solved: 1142[Submit][Status] ...
- [BZOJ 2007] [Noi2010] 海拔 【平面图最小割(对偶图最短路)】
题目链接:BZOJ - 2007 题目分析 首先,左上角的高度是 0 ,右下角的高度是 1.那么所有点的高度一定要在 0 与 1 之间.然而选取 [0, 1] 的任何一个实数,都可以用整数 0 或 1 ...
- bzoj 2007: [Noi2010]海拔【最小割+dijskstra】
上来就跑3e5的最大流--脑子抽了 很容易看出,每个地方的海拔都是0或1因为再高了没有意义,又,上去下来再上去没有意义,所以最后一定是从s连着一片0,剩下连着t一片1,然后有贡献的就是01交接的那些边 ...
- BZOJ 2007 NOI2010 海拔高度 最小减产计划
标题效果:YT城市是一个精心规划的城市.这个城市是东西向和南北向干道成n×n地区性.简单.可以YT作为一个城市广场,每个区域也可被视为一个正方形.因此,.YT市中含有(n+1)×(n+1)交叉口和2n ...
- [NOI2010]海拔(最小割)
题目描述 YT市是一个规划良好的城市,城市被东西向和南北向的主干道划分为n×n个区域.简单起见,可以将YT市看作一个 正方形,每一个区域也可看作一个正方形.从而,YT城市中包括(n+1)×(n+1)个 ...
- [bzoj 1001][Beijing2006]狼抓兔子 (最小割+对偶图+最短路)
Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的, 而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一 ...
随机推荐
- 转自知乎大神---什么是 JS 原型链?
我们知道 JS 有对象,比如 var obj = { name: 'obj' } 我们可以对 obj 进行一些操作,包括 「读」属性 「新增」属性 「更新」属性 「删除」属性 下面我们主要来看一下「读 ...
- Automate Tdxw
Automate trade module in Tdxw Code # coding: utf-8 """ Created on Thu Dec 07 10:57:45 ...
- (32位)本体学习程序(ontoEnrich)系统使用说明文档
系统运行:文件夹system下,可执行文件ontoEnrichment --------------------------------------------------------1.简单概念学习 ...
- Sublime Text 2 绿化与汉化 [Windows篇]
其实 ST3 已经出了很久了,可是我这个人恋旧,一直钟爱 ST2,所以就选择她了.最近我的 ST2 越来越卡,甚至有时候输入都会延迟1秒,所以打算自己搞个绿化版. 打开 Sublime Text 官网 ...
- java学习第04天(语句、函数、数组)
(3)循环结构 格式: for(初始化表达式,循环条件表达式,循环后的操作变大时){ 执行语句,循环体: } 注: a. for循环里面的连个表达式运行的顺序,初始化表达式只读一次,判断循环条件,为真 ...
- 【转】[.Net] 确定当前网站的物理文件路径
确定当前网站的物理文件路径 在应用程序中,您可能需要确定服务器上的文件或其他资源的路径.例如,如果应用程序以编程方式对文本文件进行读写操作,则必须为用于读取和写入的方法提供该文件的完整物理路径. 将物 ...
- 服务器环境配置安装(mysql+redis+nodejs+nginx)
公司用来测试的服务器挂了,最后重装了系统,需要重新配置程序运行环境,linux上安装不是很熟悉,特此记录一下. 首先获取系统版本信息: 参考:获取Linux系统版本信息 一.mysql 1. 安装 安 ...
- 简单解读linux的/proc下的statm、maps、memmap 内存信息文件分析【转】
转自:https://blog.csdn.net/sctq8888/article/details/7398776 转载自:http://hi.baidu.com/deep_pro/blog/item ...
- mount过程分析之六——挂载关系(图解)【转】
转自:https://blog.csdn.net/zr_lang/article/details/40343899 引言 写到这里我们已经从mount文件系统调用的入口开始,分析到内核的mount,通 ...
- JavaScript——创建对象
<script type="text/javascript"> //声明变量的首字母是小写 //1.对象字面量 /*var person = { name:" ...