思路:

1.按照题意求最小割 转换成最大流用Dinic解

2. 转换成对偶图 求最短路

Dinic:

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define N 1100000
int n,m,first[N],next[N*6],v[N*6],w[N*6],tot,jy,ans,vis[N],S,T,xx,pos[N];
void Add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
void add(int x,int y,int z){Add(x,y,z),Add(y,x,z);}
bool tell(){
memset(vis,-1,sizeof(vis)),vis[S]=0;
queue<int>q;q.push(S);
while(!q.empty()){
int t=q.front();q.pop();
for(int i=first[t];~i;i=next[i])
if(w[i]&&vis[v[i]]==-1)
vis[v[i]]=vis[t]+1,q.push(v[i]);
}return vis[T]!=-1;
}
int zeng(int x,int y){
if(x==T)return y;
int r=0;
for(int i=first[x];~i&&y>r;i=next[i])
if(w[i]&&vis[v[i]]==vis[x]+1){
int t=zeng(v[i],min(y-r,w[i]));
w[i]-=t,w[i^1]+=t,r+=t;
}
if(!r)vis[x]=-1;
return r;
}
int main(){
memset(first,-1,sizeof(first));
scanf("%d%d",&n,&m);
S=m+1,T=n*m+m;
for(int i=1;i<=n;i++)for(int j=1;j<m;j++)
scanf("%d",&xx),add(i*m+j,i*m+j+1,xx);
for(int i=1;i<n;i++)for(int j=1;j<=m;j++)
scanf("%d",&xx),add(i*m+j,(i+1)*m+j,xx);
for(int i=1;i<n;i++)for(int j=1;j<m;j++)
scanf("%d",&xx),add(i*m+j,(i+1)*m+j+1,xx);
while(tell())while(jy=zeng(S,0x3fffffff))ans+=jy;
printf("%d\n",ans);
}

Dijkstra:



这么转成对偶图

在原平面图中添加一条从起点S到终点T的边,会增加一个区域S’。

无限大的区域设为T’。

把加边后的平面图按照上面的方法转化为对偶图。

删去边S’-T’。

此时S-T的最小割大小等于S’到T’的最短路长度。

Ps:需要特判n=1|m=1的情况

//By SiriusRen
#include <queue>
#include <cstdio>
#include <cstring>
using namespace std;
#define M 1111*1111*6
int n,m,a[1005][1005],b[1005][1005],c[1005][1005],T=2000*1005;
int first[M/3],next[M],v[M],w[M],tot,vis[M/3],d[M/3];
void Add(int x,int y,int z){w[tot]=z,v[tot]=y,next[tot]=first[x],first[x]=tot++;}
struct Node{int now,weight;}jy;
bool operator < (Node a,Node b){return a.weight>b.weight;}
void Dijkstra(){
priority_queue<Node>pq;pq.push(jy);
while(!pq.empty()){
Node t=pq.top();pq.pop();
if(vis[t.now])continue;
for(int i=first[t.now];~i;i=next[i])if(d[v[i]]>d[t.now]+w[i])
d[v[i]]=d[t.now]+w[i],jy.now=v[i],jy.weight=d[v[i]],pq.push(jy);
}printf("%d\n",d[T]=0x3f3f3f3f?d[T]:0);
}
void add(int x,int y,int z){Add(x,y,z),Add(y,x,z);}
int main(){
memset(first,-1,sizeof(first)),memset(d,0x3f,sizeof(d)),d[0]=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)for(int j=1;j<m;j++)scanf("%d",&a[i][j]);
for(int i=1;i<n;i++)for(int j=1;j<=m;j++)scanf("%d",&b[i][j]);
for(int i=1;i<n;i++)for(int j=1;j<m;j++)scanf("%d",&c[i][j]);
if(n==1||m==1){
if(m==1)for(int i=1;i<n;i++)d[T]=min(d[T],b[i][1]);
if(n==1)for(int i=1;i<m;i++)d[T]=min(d[T],a[1][i]);
}
for(int i=1;i<n;i++)for(int j=1;j<m;j++){
int cnt=((i-1)*(m-1)+j)*2;
add(cnt-1,cnt,c[i][j]);
if(j!=m-1)add(cnt-1,cnt+2,b[i][j+1]);
if(i!=n-1)add(cnt,cnt+(m-1)*2-1,a[i+1][j]);
}
for(int i=1;i<n;i++)add(((i-1)*(m-1)+1)*2,T,b[i][1]),add(0,2*i*(m-1)-1,b[i][m]);
for(int i=1;i<m;i++)add(0,2*i-1,a[1][i]),add(2*((n-2)*(m-1)+i),T,a[n][i]);
Dijkstra();
}



效率竟然差不多?

BZOJ 1001 平面图与对偶图的转化 最短路Or最大流的更多相关文章

  1. bzoj 1001 平面图转对偶图 最短路求图最小割

    原题传送门http://www.lydsy.com/JudgeOnline/problem.php?id=1001 整理了下之前A的题 平面图可以转化成对偶图,然后(NlogN)的可以求出图的最小割( ...

  2. BZOJ 1001 平面图转对偶图

    原图的面转成点,原图的边依旧边,只是连接的是两个面. 对偶图的点数=原图的面数 对偶图的边数=原图的边数(如果原边只属于一个面,则它为环边) #include<bits/stdc++.h> ...

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

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

  4. [jzoj 6092] [GDOI2019模拟2019.3.30] 附耳而至 解题报告 (平面图转对偶图+最小割)

    题目链接: https://jzoj.net/senior/#main/show/6092 题目: 知识点--平面图转对偶图 在求最小割的时候,我们可以把平面图转为对偶图,用最短路来求最小割,这样会比 ...

  5. BZOJ 1001 狼抓兔子 (网络流最小割/平面图的对偶图的最短路)

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1001 算法讨论: 1.可以用最大流做,最大流等于最小割. 2.可以把这个图转化其对偶图,然 ...

  6. BZOJ 1001 [BeiJing2006] 狼抓兔子(平面图最大流)

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

  7. s - t 平面图最大流 (附例题 bzoj 1001)

    以下均移自 周冬的<两极相通-浅析最大最小定理在信息学竞赛中的应用> 平面图性质 1.(欧拉公式)如果一个连通的平面图有n个点,m条边和f个面,那么f=m-n+2 2.每个平面图G都有一个 ...

  8. 【BZOJ 1001】狼抓兔子 对偶图+SPFA

    这道题是求图的最小割,也就是用最大流.但因为边太多,最大流算法会T,因此不能用最大流算法. 因为这是个平面图,所以求平面图的最小割可以使用特殊的技巧就是求对偶图然后求对偶图的最短路.把每个面看成一个点 ...

  9. 【BZOJ 2007】 2007: [Noi2010]海拔 (平面图转对偶图+spfa)

    2007: [Noi2010]海拔 Time Limit: 20 Sec  Memory Limit: 552 MBSubmit: 2504  Solved: 1195 Description YT市 ...

随机推荐

  1. JavaScript DOM(一)

    文件夹: DOM家谱树 节点的基本属性和方法 document与getElement方法 DOM家谱树 DOM能够将不论什么HTML或XML文档描绘成一个由多层次节点构成的结构.当中节点被分为几种不同 ...

  2. QT中|Qt::Tool类型窗口自动退出消息循环问题解决(setQuitOnLastWindowClosed必须设置为false,最后一个窗口不显示的时候,程序会退出消息循环)

    为application 设置setQuitOnLastWindowClosed属性,确实为true: 将其显示为false; 退出该应该程序不能调用QDialog的close消息槽,只能调用qApp ...

  3. js解析网络中的json数据

    <?php echo <<<_END <html> <head> </head> <body> <div id=" ...

  4. bzoj1218: [HNOI2003]激光炸弹(DP二维前缀和)

    1218: [HNOI2003]激光炸弹 题目:传送门 题解: 一道经典题目啊... 为了更好的操作...把整个坐标系向右上角移动,从(1,1)开始 那么f[i][j]统计一下以(i,j)作为右上角, ...

  5. 发送HTTP请求 -- HttpUtil

    1. package com.step.utils; import java.io.IOException; import java.net.URLDecoder; import java.util. ...

  6. 11.使用boostregex遭遇无法打开libboost_regex-vc120-mt-sgd-1_62.lib的问题

    通过Boost库可以在C++项目中使用正则表达式,配置好环境后链接过程出现”无法打开libboost_regex-vc120-mt-sgd-1_62.lib”的错误.  原因是按照官方生成lib的方法 ...

  7. 使用ffmpeg批量合并flv文件

    title: 使用ffmpeg批量合并flv文件 toc: false date: 2018-10-14 16:08:19 categories: methods tags: ffmpeg flv 使 ...

  8. C#使用tesseract3.02识别验证码模拟登录

    一.前言 使用tesseract3.02识别有验证码的网站 安装tesseract3.02 在VS nuget 搜索Tesseract即可. 二.项目结构图 三.项目主要代码 using System ...

  9. win-visualviewport-space

    html.win-hoverable <div class="win-visualviewport-space"></div> <section cl ...

  10. word2tex之类的问题

    首先就是这个word2tex一般是在word和tex文本互相转换的时候用的. 以前win7下用的chikrii忘了使用方法.. 之后再win10下用的excel2tex,但是转换时候总感觉不如word ...