题意:有一张平面图,求它的最小割。N,M.表示网格的大小,N,M均小于等于1000.

左上角点为(1,1),右下角点为(N,M).有以下三种类型的道路 
1:(x,y)<==>(x+1,y) 
2:(x,y)<==>(x,y+1) 
3:(x,y)<==>(x+1,y+1) 
 
思路:第一眼看就是一个最小割=最大流,但点数1000000,边数6000000过大
所以要平面图最小割转最短路 详情见周驿东《浅析最大最小定理在信息学竞赛中的应用》
n=1和m=1要特判,链状的我也母鸡为什么会错,特判就对了
 var q:array[..]of longint;
dis,head:array[..]of longint;
inq:array[..]of boolean;
vet,next,len:array[..]of longint;
num:array[..,..,..]of longint;
n,m,i,j,x,tot,st,ed,s,ans:longint; procedure add(a,b,c:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
head[a]:=tot;
end; function min(x,y:longint):longint;
begin
if x<y then exit(x);
exit(y);
end; procedure spfa;
var t,w,e,v,u:longint;
begin
fillchar(dis,sizeof(dis),$1f);
fillchar(inq,sizeof(inq),false);
t:=-; w:=; q[]:=st; dis[st]:=; inq[st]:=true;
while t<w do
begin
inc(t); u:=q[t mod (ed+)];
inq[u]:=false;
e:=head[u];
while e<> do
begin
v:=vet[e];
if dis[u]+len[e]<dis[v] then
begin
dis[v]:=dis[u]+len[e];
if not inq[v] then
begin
inc(w); q[w mod (ed+)]:=v;
inq[v]:=true;
end;
end;
e:=next[e];
end;
end;
writeln(dis[ed]);
end; begin
//assign(input,'bzoj1001.in'); reset(input);
//assign(output,'bzoj1001.out'); rewrite(output);
readln(n,m);
if (n=)and(m=) then
begin
writeln();
exit;
end;
if n= then
begin
ans:=maxlongint;
for i:= to m- do begin read(x); ans:=min(ans,x); end;
writeln(ans);
exit;
end;
if m= then
begin
ans:=maxlongint;
for j:= to n- do begin read(x); ans:=min(ans,x); end;
writeln(ans);
exit;
end; for i:= to n do
for j:= to m do
begin
inc(s); num[i,j,]:=s;
inc(s); num[i,j,]:=s;
end;
inc(s);
st:=s; ed:=s+;
for i:= to n do
for j:= to m- do
begin
read(x);
if i= then
begin
add(st,num[i,j,],x);
add(num[i,j,],st,x);
end
else if i=n then
begin
add(ed,num[i-,j,],x);
add(num[i-,j,],ed,x);
end
else
begin
add(num[i-,j,],num[i,j,],x);
add(num[i,j,],num[i-,j,],x);
end;
end;
for i:= to n- do
for j:= to m do
begin
read(x);
if j= then
begin
add(num[i,j,],ed,x);
add(ed,num[i,j,],x);
end
else if j=m then
begin
add(num[i,j-,],st,x);
add(st,num[i,j-,],x);
end
else
begin
add(num[i,j-,],num[i,j,],x);
add(num[i,j,],num[i,j-,],x);
end;
end;
for i:= to n- do
for j:= to m- do
begin
read(x);
add(num[i,j,],num[i,j,],x);
add(num[i,j,],num[i,j,],x);
end;
spfa;
// close(input);
//close(output);
end.

UPD(2018.10.17):C++

 #include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<map>
#include<set>
#include<queue>
#include<vector>
using namespace std;
typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef pair<int,int> PII;
typedef vector<int> VI;
#define fi first
#define se second
#define MP make_pair
#define N 2100000
#define M 6100000
#define eps 1e-8
#define pi acos(-1)
#define oo 1e9 int num[][][],q[N],dis[N],head[N],inq[N],
vet[M],nxt[M],len[M],tot,s,st,ed; int add(int a,int b,int c)
{
nxt[++tot]=head[a];
vet[tot]=b;
len[tot]=c;
head[a]=tot;
} void spfa(int st,int ed)
{
memset(dis,0x3f,sizeof(dis));
memset(inq,,sizeof(inq));
int t=; int w=; q[]=st; dis[st]=; inq[st]=;
while(t<w)
{
t++; int u=q[t%(s+)];
inq[u]=;
int e=head[u];
while(e)
{
int v=vet[e];
if(dis[u]+len[e]<dis[v])
{
dis[v]=dis[u]+len[e];
if(!inq[v])
{
w++; q[w%(s+)]=v;
inq[v]=;
}
}
e=nxt[e];
}
}
printf("%d\n",dis[ed]);
} int main()
{
//freopen("bzoj1001.in","r",stdin);
//freopen("bzoj1001.out","w",stdout);
int n,m;
scanf("%d%d",&n,&m);
if(n==&&m==){printf("0\n"); return ;}
if(n==)
{
int ans=oo;
for(int i=;i<m;i++)
{
int x;
scanf("%d",&x);
ans=min(ans,x);
}
printf("%d\n",ans);
return ;
}
if(m==)
{
int ans=oo;
for(int i=;i<n;i++)
{
int x;
scanf("%d",&x);
ans=min(ans,x);
}
printf("%d\n",ans);
return ;
}
s=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
for(int k=;k<=;k++) num[i][j][k]=++s;
int st=++s;
int ed=++s;
for(int i=;i<=n;i++)
for(int j=;j<=m-;j++)
{
int x;
scanf("%d",&x);
if(i==)
{
add(st,num[i][j][],x);
add(num[i][j][],st,x);
}
else if(i==n)
{
add(ed,num[i-][j][],x);
add(num[i-][j][],ed,x);
}
else
{
add(num[i-][j][],num[i][j][],x);
add(num[i][j][],num[i-][j][],x);
}
} //横边
for(int i=;i<=n-;i++)
for(int j=;j<=m;j++)
{
int x;
scanf("%d",&x);
if(j==)
{
add(num[i][j][],ed,x);
add(ed,num[i][j][],x);
}
else if(j==m)
{
add(num[i][j-][],st,x);
add(st,num[i][j-][],x);
}
else
{
add(num[i][j-][],num[i][j][],x);
add(num[i][j][],num[i][j-][],x);
}
} //纵边 for(int i=;i<=n-;i++)
for(int j=;j<=m-;j++)
{
int x;
scanf("%d",&x);
add(num[i][j][],num[i][j][],x);
add(num[i][j][],num[i][j][],x);
} //斜边
spfa(st,ed);
return ;
}

【BZOJ1001】狼抓兔子(平面图最小割转最短路)的更多相关文章

  1. BZOJ1001/LG4001 「ICPC Beijing2006」狼抓兔子 平面图最小割转对偶图最短路

    问题描述 BZOJ1001 LG4001 题解 平面图最小割=对偶图最短路 假设起点和终点间有和其他边都不相交的一条虚边. 如图,平面图的若干条边将一个平面划分为若干个图形,每个图形就是对偶图中的一个 ...

  2. [BZOJ1001][BeiJing2006]狼抓兔子(最小割转最短路|平面图转对偶图)

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec  Memory Limit: 162 MBSubmit: 31805  Solved: 8494[Submit][ ...

  3. BZOJ-1001 狼抓兔子 (最小割-最大流)平面图转对偶图+SPFA

    1001: [BeiJing2006]狼抓兔子 Time Limit: 15 Sec Memory Limit: 162 MB Submit: 14686 Solved: 3513 [Submit][ ...

  4. BZOJ1001:狼抓兔子(最小割最大流+vector模板)

    1001: [BeiJing2006]狼抓兔子 Description 现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨, ...

  5. bzoj 1001 狼抓兔子 —— 平面图最小割(最短路)

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1001 平面图最小割可以转化成最短路问题: 建图时看清楚题目的 input ... 代码如下: ...

  6. bzoj 1001: [BeiJing2006]狼抓兔子 平面图最小割

    平面图跑最大流 可以转换为其对偶图跑最短路 一个环对应一个割  找到最小环(即最短路)极为所求,注意辅助边的建立 加入读入优化  不过时间还是一般  估计是dij写的不好   大神勿喷~~~ /*** ...

  7. 2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割)

    2021.12.02 P4001 [ICPC-Beijing 2006]狼抓兔子(最小割) https://www.luogu.com.cn/problem/P4001 题意: 把图分成两部分需要的最 ...

  8. BZOJ1001 BJOI2006狼抓兔子(最小割+最短路)

    显然答案就是最小割.直接跑dinic也能过,不过显得不太靠谱. 考虑更正确的做法.作为一个平面图,如果要把他割成两半,那么显然可以用一条曲线覆盖且仅覆盖所有割边.于是我们把空白区域看成点,隔开他们的边 ...

  9. BZOJ_2001_[BeiJing2006]狼抓兔子_最小割转对偶图

    BZOJ_2001_[BeiJing2006]狼抓兔子 题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 分析:思路同NOI2010海拔. ...

  10. BZOJ1001 狼抓兔子 平面图转对偶图 最小割

    现在小朋友们最喜欢的"喜羊羊与灰太狼",话说灰太狼抓羊不到,但抓兔子还是比较在行的,而且现在的兔子还比较笨,它们只有两个窝,现在你做为狼王,面对下面这样一个网格的地形: 左上角点为 ...

随机推荐

  1. Java基础面试操作题: 线程问题,写一个死锁(原理:只有互相都等待对方放弃资源才会产生死锁)

    package com.swift; public class DeadLock implements Runnable { private boolean flag; DeadLock(boolea ...

  2. cocos2dx通过ndk编译c++库

    ndk编译c++库,然后通过jni调用实现重要代码封装,是安卓应用中最常用的技术,一方面可以将重要的代码实现隐藏,防止泄漏,也可以提高打包速度. ndk里面的sample文件夹中有很多实用的例子,其中 ...

  3. 【模板】无旋Treap(FHQ)

    如题,这是一个模板... #include <algorithm> #include <iostream> #include <cstring> #include ...

  4. css制作三角形,下拉框三角形

    网站制作中常常需要下拉框,而如果下拉框如果只是单纯的矩形则会显得太过单调,所以这次教大家利用css制作三角形放在矩形上面 首先利用css制作三角形 div { width:0px; height:0p ...

  5. Restful API 概念解析

    什么是restful? REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”. ...

  6. Altium Designer入门学习笔记4:PCB设计中各层的含义

    阻焊层:solder mask,是指板子上要上绿油的部分:因为它是负片输出,所以实际上有solder mask的部分实际效果并不上绿油,而是镀锡,呈银白色! 助焊层:paste mask,是机器贴片时 ...

  7. leetcode-14-basic-breadthFirstSearch

    BFS: breadth first search 107. Binary Tree Level Order Traversal II 解题思路: 本来我是用map<int,int>存所有 ...

  8. hdu-1231 连续最大子序列(动态规划)

    Time limit1000 ms Memory limit32768 kB 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj ...

  9. Gym - 101775L SOS 博弈 找规律

    题目:https://cn.vjudge.net/problem/Gym-101775L PS:训练赛中被这道题折磨的不轻,和队友反复推必胜态与必败态试图推导出公式或者规律,然后推的心态逐渐失控,,, ...

  10. Django之include本质

    一. URL name详解 from django.conf.urls import url from django.contrib import admin from calc import vie ...