您的位置:首页 > 其它

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

2018-08-03 19:52 260 查看

  显然答案就是最小割。直接跑dinic也能过,不过显得不太靠谱。

  考虑更正确的做法。作为一个平面图,如果要把他割成两半,那么显然可以用一条曲线覆盖且仅覆盖所有割边。于是我们把空白区域看成点,隔开他们的边看成边,原图的最小割就是这张新图中能割开原起点和终点的两个区域之间的最短路。

  建出来的新图就是原图的对偶图。平面图最小割=对偶图最短路。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define N 1010
#define S 2000000
#define T 2000001
int n,m,d[N*N<<1],p[N*N<<1],t=0;
struct data{int to,nxt,len;
}edge[N*N*6];
bool flag[N*N<<1];
struct point
{
int x,d;
bool operator <(const point&a) const
{
return d>a.d;
}
};
priority_queue<point> q;
int trans(int x,int y,int p)
{
if (x==0) return S;
if (x==n) return T;
if (y==0) return T;
if (y==m) return S;
return ((x-1)*(m-1)+(y-1)<<1)+p;
}
void addedge(int x,int y,int z)
{
t++;edge[t].to=y,edge[t].nxt=p[x],edge[t].len=z,p[x]=t;
t++;edge[t].to=x,edge[t].nxt=p[y],edge[t].len=z,p[y]=t;
}
void dijkstra()
{
q.push((point){S,0});
memset(d,42,sizeof(d));d[S]=0;
for (int i=1;i<=trans(n,m,1)+2;i++)
{
while (!q.empty()&&flag[q.top().x]) q.pop();
if (q.empty()) break;
point k=q.top();q.pop();
flag[k.x]=1;
for (int j=p[k.x];j;j=edge[j].nxt)
if (k.d+edge[j].len<d[edge[j].to])
{
d[edge[j].to]=k.d+edge[j].len;
q.push((point){edge[j].to,d[edge[j].to]});
}
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj1001.in","r",stdin);
freopen("bzoj1001.out","w",stdout);
const char LL[]="%I64d";
#else
const char LL[]="%lld";
#endif
n=read(),m=read();
for (int i=1;i<=n;i++)
for (int j=1;j<m;j++)
{
int x=read();
addedge(trans(i-1,j,1),trans(i,j,0),x);
}
for (int i=1;i<n;i++)
for (int j=1;j<=m;j++)
{
int x=read();
addedge(trans(i,j-1,0),trans(i,j,1),x);
}
for (int i=1;i<n;i++)
for (int j=1;j<m;j++)
{
int x=read();
addedge(trans(i,j,0),trans(i,j,1),x);
}
dijkstra();
cout<<d[T];
return 0;
}

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: