问题描述

BZOJ2007

LG2046


题解

发现左上角海拔为 \(0\) ,右上角海拔为 \(1\) 。

上坡要付出代价,下坡没有收益,所以有坡度的路越少越好。

所以海拔为 \(1\) 的点,和海拔为 \(0\) 的点,一定能够在这个网格图中由一条连续的线划分为两个集合。

将一个图中的所有结点划分为两个集合,显然为最小割模型。

又发现是网格图,所以平面图最小割转化为对偶图最短路。


\(\mathrm{Code}\)

不删调试见祖宗

#include<bits/stdc++.h>
using namespace std; const int maxn=500*500+3; int n,S,T;
int Head[maxn],to[maxn*5],Next[maxn*5],w[maxn*5],tot=1;
int fr[maxn*5]; void add(int x,int y,int z){
fr[++tot]=y,to[tot]=x,Next[tot]=Head[y],Head[y]=tot,w[tot]=z;
} int id(int x,int y){
return (x-1)*n+y;
} void Init(void){
scanf("%d",&n);
} void WestToEast(void){
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(id(1,i),S,x);
}
for(int i=2;i<=n;i++){
for(int j=1,x;j<=n;j++){
scanf("%d",&x);
add(id(i,j),id(i-1,j),x);
}
}
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(T,id(n,i),x);
}
} void NorthToSouth(void){
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(T,id(i,1),x);
for(int j=2;j<=n;j++){
scanf("%d",&x);
add(id(i,j-1),id(i,j),x);
}
scanf("%d",&x);
add(id(i,n),S,x);
}
} void EastToWest(void){
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(S,id(1,i),x);
}
for(int i=2;i<=n;i++){
for(int j=1,x;j<=n;j++){
scanf("%d",&x);
add(id(i-1,j),id(i,j),x);
}
}
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(id(n,i),T,x);
}
} //n lines
//n+1 every-line void SouthToNorth(void){
for(int i=1,x;i<=n;i++){
scanf("%d",&x);
add(id(i,1),T,x);
for(int j=2;j<=n;j++){
scanf("%d",&x);
add(id(i,j),id(i,j-1),x);
}
scanf("%d",&x);
add(S,id(i,n),x);
}
} void debug(){
printf("\n### S = %d\n",S);
printf("### T = %d\n\n",T);
for(int i=2;i<=tot;i++){
printf("*** From %d To %d , val = %d\n",fr[i],to[i],w[i]);
}
} void Graph_build(void){
S=n*n+1,T=S+1;
WestToEast();
NorthToSouth();
EastToWest();
SouthToNorth();
} int dis[maxn];
bool vis[maxn];
#define pii(x,y) make_pair(x,y) void dijkstra(void){
memset(dis,0x3f,sizeof(dis));
priority_queue<pair<int,int> >q;
q.push(pii(0,S));dis[S]=0;
while(!q.empty()){
int x=q.top().second;q.pop();
if(vis[x]) continue;vis[x]=1;
if(x==T) return;
for(int i=Head[x];i;i=Next[i]){
int y=to[i];
if(dis[y]>dis[x]+w[i]){
dis[y]=dis[x]+w[i];
q.push(pii(-dis[y],y));
}
}
}
} void Work(void){
Graph_build();
#ifndef ONLINE_JUDGE
// debug();
#endif
dijkstra();
printf("%d\n",dis[T]);
} int main(){
#ifndef ONLINE_JUDEG
// freopen("hzlbn.in","r",stdin);
#endif
Init();
Work();
return 0;
}

最新文章

  1. CentOS 下使用yum安装nodejs
  2. myBatis的一对多查询,主要利用resultMap实现一次查询多个结果集
  3. Java多线程系列--“基础篇”02之 常用的实现多线程的两种方式
  4. Jexus-5.6.3使用详解、Jexus Web Server配置
  5. 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案
  6. iOS7以上图片模糊效果
  7. servers无法输入server name
  8. 使用jQuery库改造ajax
  9. http://www.360doc.com/content/10/1012/09/3722251_60285817.shtml
  10. Toad for Oracle 12 download link
  11. LoadLibraryEx及发回hmodule的一些细节
  12. bzoj1072
  13. IP分片和TCP分片 MTU和MSS(转)
  14. Scrapy开发
  15. x240 uefi ubuntu 12.04.4
  16. Python操作redis系列之 列表(list) (五)(转)
  17. go标准库的学习-net/rpc
  18. JQ实现弹幕效果
  19. 【转载】TCP 与 UDP 的区别
  20. js数组的比较

热门文章

  1. 【Puppeteer】puppeteer安装/常用的方法以及一个小栗子(Youtube油管自动评论)
  2. Cesium专栏-卫星轨迹
  3. C# SendAysnc 超时
  4. 45-管理 Machine
  5. Mybatis XML映射文件
  6. 截取字符串substr和substring两者的区别
  7. js获取数组最大值或最小值
  8. asp开发类型判段
  9. java之instanceof操作符
  10. 【Unity游戏开发】Android6.0以上的动态权限申请问题