BZOJ 1001 狼抓兔子

题面

题解

  平面图上网络流转最短路。

  题意可转化为求左上角到右下角的最大流。根据最大流最小割定理,网络流中最大流的值等于最小割的容量。由于本题中给出的网络流是平面图,可以用最短路在几何意义上算出最小割:

  对每一个封闭区域 \(u\) 建点 \(u'\),对每两个相接的封闭区域 \(u,v\) 的公共边 \(e\) 建边 \(e'\) 连接 \(u',v'\)\(e'\) 的权值等于 \(e\) 的流量,如果把选取 \(e'\) 看作割断 \(e\),那么求网络流的最小割就可以等效为选取权值和尽可能小的 \(e'\),使得图的左下方和右上方联通,而这个问题可以用最短路来解决。复杂度 \(O(nm\log(nm))\)

代码

查看代码

#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const ll inf=1e18;
const int maxn=2e6+5,maxm=6e6+5;
int hea[maxn],nex[maxm],to[maxm],wei[maxm],tot;
struct node{
    int u; ll d;
    node(int u=0,ll d=0):u(u),d(d){}
};
bool operator < (const node &a,const node &b){
    return a.d>b.d;
}
ll dis[maxn];
priority_queue<node> que;
void dijkstra(int s,int n){
    int i,ed;
    int u,v,w;
    ll d;
    node tmp;
    for (i=0;i<n;i++) dis[i]=inf;
    while (!que.empty()) que.pop();
    que.push(node(s,dis[s]=0));
    while (!que.empty()){
        tmp=que.top(); que.pop(); u=tmp.u; d=tmp.d;
        if (d>dis[u]) continue;
        for (ed=hea[u];ed;ed=nex[ed]){
            v=to[ed]; w=wei[ed];
            if (dis[v]>d+w) que.push(node(v,dis[v]=(d+w)));
        }
    }
}
int n,m,s,t;
inline int getid(int x,int y,int z){
    if (x<1||y>=m) return s;
    if (x>=n||y<1) return t;
    return (x-1)*(m-1)*2+y*2-z;
}
void add(int u,int v,int w){
    tot++;
    nex[tot]=hea[u];
    hea[u]=tot;
    to[tot]=v;
    wei[tot]=w;
}
int main(){
    int i,j;
    int u,v,w;
    scanf("%d%d",&n,&m); s=0; t=(n-1)*(m-1)*2+1; tot=0;
    for (i=1;i<=n;i++) for (j=1;j<m;j++){
        scanf("%d",&w);
        u=getid(i-1,j,1); v=getid(i,j,0);
        add(u,v,w); add(v,u,w);
    }
    for (i=1;i<n;i++) for (j=1;j<=m;j++){
        scanf("%d",&w);
        u=getid(i,j-1,0); v=getid(i,j,1);
        add(u,v,w); add(v,u,w);
    }
    for (i=1;i<n;i++) for (j=1;j<m;j++){
        scanf("%d",&w);
        u=getid(i,j,1); v=getid(i,j,0);
        add(u,v,w); add(v,u,w);
    }
    dijkstra(s,t+1);
    printf("%lld\n",dis[t]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Kilo-5723/p/11955410.html