BZOJ 1001オオカミはウサギを捕まえました

フェイス質問

問題の解決策

  ネットワークフローの最短平面図。

  質問の意味することは右下隅に左上のための最大流量に変換することができます。最大流量の定理、ネットワークフローは、カットの最大流量容量の最小値に等しいです。このネットワーク・フローの問題は、平面視で与えられているので、最短幾何学的に最小カットを計算するのに使用することができます。

  各閉領域のための\(U \)内蔵点\(U '\)各閉鎖コンタクト領域、2つの\(U、V \)共通のエッジ\(E \)内蔵エッジ\(E' \ )接続)\ \(U 'V'を\ (E ')\ 重みが等しい\(E \)トラフィック、場合に選択\)\(E'考えカット\(E \)次にシーク最小のネットワークストリームの切断は、可能な限り小さなとして当量を選択することができる\(E「\)左下と右上図ユニコムのが、この問題は、最短経路で解決することができるように、。複雑\(O(NM \ログ(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