思路:

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. python-Pymyslql-requests_html:把腾讯新闻的今日推荐和链接存进数据库

    使用pumsql封装的部分功能 request_html:打开www.qq.com的例子 结果: PS:记得处理数据

  2. nginx源代码分析--从源代码看nginx框架总结

    nginx源代码总结: 1)代码中没有特别绕特别别扭的编码实现.从变量的定义调用函数的实现封装,都非常恰当.比方从函数命名或者变量命名就能够看出来定义的大体意义,函数的基本功能,再好的架构实如今编码习 ...

  3. hdu 4966 最小树形图

    将每门课等级拆成0,1,2,3...a[i]个点,对每一个等级大于0的点向它低一级连边,权值为0[意思是,若修了level k.则level(0~k)都当做修了] 将输入的边建边,权值为money[i ...

  4. c# 获取一年中的周/根据一年中的第几周获取该周的开始日期与结束日期

    /// <summary> /// 获取一年中的周 /// </summary> /// <param name="dt">日期</par ...

  5. Perl怎样过滤html标签

    比方一串字符串 <div><b>123</b></div> 假设仅仅想拿到123怎么办呢? 用perl的正則表達式能够非常easy的做到. $str = ...

  6. ubuntu 下的文件校验(md5、sha256)

    在本地使用 md5sum/sha256sum 生成某待测文件的 hash 值,以跟标准文件的 hash 值做对比验证,确定经网络传输过程得到的文件是否真实无损.一般而言,hash 值如果一致,大概率上 ...

  7. BZOJ 3160 FFT+Manacher

    思路: 这道题思路好奇怪--. 我们先要知道关于x (x可以是间隙) 对称的有几对字母 显然暴力是n^2的 那怎么办呢 先把所有'a'看成1 'b'看成0 意外的发现 这不就是卷积嘛 再倒过来搞一搞 ...

  8. HD-ACM算法专攻系列(9)——大菲波数

    题目描述: 源码: 运用Java大数求解. import java.math.BigInteger; import java.util.*; public class Main { //主函数 pub ...

  9. H5中 input消除默认,取消在手机上的点击高亮效果

    input消除默认,代码如下    input{             -webkit-tap-highlight-color: rgba(255, 255, 255, 0);            ...

  10. Dapper Dapper-Extensions

    之前公司在开发项目的时候有用到过Dapper 仓储 以及IOC Castel .最近新项目上想使用上这些技术,决定新学习一下. 看了很多资料,发现几个比较容易菜鸟的我理解的,整理下来,找时间好好整理一 ...