zoukankan      html  css  js  c++  java
  • 平面图最大流

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

    连接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
  • 相关阅读:
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Symmetric Tree
    Best Time to Buy and Sell Stock II
    Best Time to Buy and Sell Stock
    Triangle
    Populating Next Right Pointers in Each Node II
    Pascal's Triangle II
    Pascal's Triangle
    Populating Next Right Pointers in Each Node
  • 原文地址:https://www.cnblogs.com/zhujiangning/p/5549648.html
Copyright © 2011-2022 走看看