平面图最大流

建出对偶图,最短路即最大流

连接s,t形成的面为新的s,外围都是新的t,

有向图连边方向视情况而定

#include<cstdio>
#include<cstring>
#include<queue>
#define LL long long
#define INF 1000000000
using namespace std;

  LL dis[500000];
  int b[500000];
  int next[5000000],des[5000000],cnt=0,nd[500000],n;
  LL len[5000000];
  
  struct data{
      int num;
      LL dis;
       bool operator <(const data &a)const {
          return (a.dis<dis);
      }
  };
  priority_queue <data> heap;

  void addedge(int u,int v,int l){
      next[++cnt]=nd[u];nd[u]=cnt;
      des[cnt]=v;len[cnt]=l;
  }
  
  void build(){
      int t;
      memset(nd,-1,sizeof(nd));
      
      for (int i=1;i<=n+1;i++)
        for (int j=1;j<=n;j++){
               scanf("%d",&t);
               if (i==1) addedge((i-1)*n+j,n*n+1,t);else
               if (i==n+1) addedge(0,(i-2)*n+j,t);else
               addedge((i-1)*n+j,(i-2)*n+j,t);
        }
        
    for (int i=1;i<=n;i++)
     for (int j=0;j<=n;j++){
         scanf("%d",&t);
         if (j==0) addedge(0,(i-1)*n+j+1,t);else
         if (j==n) addedge(i*n,n*n+1,t);else
         addedge((i-1)*n+j,(i-1)*n+j+1,t);
     }
     
    for (int i=1;i<=n+1;i++)
      for (int j=1;j<=n;j++){
          scanf("%d",&t);
          if (i==1) addedge(n*n+1,(i-1)*n+j,t);else
          if (i==n+1) addedge((n-1)*n+j,0,t);else 
          addedge((i-2)*n+j,(i-1)*n+j,t);
      }     
      
    for (int i=1;i<=n;i++)
      for (int j=0;j<=n;j++){
          scanf("%d",&t);
          if (j==0) addedge((i-1)*n+j+1,0,t);else
          if (j==n) addedge(n*n+1,(i-1)*n+j,t);else
          addedge((i-1)*n+j+1,(i-1)*n+j,t);
      }  
  }
  
  void dij(){
      int tcnt;
      for (int i=0;i<=n*n+1;i++) {data t;t.num=i;t.dis=dis[i];heap.push(t);}
    
    
    while (!heap.empty()){
        data t=heap.top();
        heap.pop();
        if (b[t.num]) continue;
        for (int p=nd[t.num];p!=-1;p=next[p])
          if (dis[des[p]]>dis[t.num]+len[p]){
              tcnt++;
            dis[des[p]]=dis[t.num]+len[p];
            data tmp;tmp.num=des[p];tmp.dis=dis[des[p]];
            heap.push(tmp);
        }
        b[t.num]=1;                        
    }
  }

  int main(){
      scanf("%d",&n);
      
      build();
      a
      for (int i=1;i<500000;i++) dis[i]=1000000000;
      memset(b,0,sizeof(b));
      dis[0]=0;
    dij();
      
      printf("%lld",dis[n*n+1]);
  }//BZOJ2007

 

posted @ 2016-06-01 15:03  z1j1n1  阅读(379)  评论(0编辑  收藏  举报