[24 network flow problem] 16. The digital keystone problem solving report (maximum cost maximum flow)

16. The digital keystone issue

The meaning of problems

It has a trapezoidal digits,

The ladder has \ (n-\) line, the first line \ (m \) columns, each row a plurality than the previous row.

There \ (m \) strip from the top of the trapezoid in the end portion of the path, respectively a first row of \ (m \) element as a starting point, each lower left or lower right can move.

When the answer to the following three conditions are satisfied, respectively, \ (m \) the maximum value of the digital sum paths.

  1. \ (m \) paths are mutually exclusive.
  2. \ (m \) paths can be the point of intersection, the edge may not intersect.
  3. \ (m \) paths may be the point of intersection, the edge may intersect.


Thinking

The questions in fact DAG disjoint various variants path.

The first question, in accordance with the routine, each point can appear only once, then put into each point point and out point , even a capacity between in- and out-points \ (1 \) , consideration of \ ( 0 \) side, running maximum cost maximum flow on the line.

The second question, could have been built without the in and out points, but we have to avoid redundant construction diagram, you can directly point to the edge capacity points instead \ (INF \) , others, like the original. Note that it can not be changed after the maximum flow edge weights run directly on the residual network, because then could not find the augmenting path.

The third question, wanted to start a \ (dp \) is the title given .... but who then put some face ... except from the source (S \) \ outside edge out of practice, all sides right side are replaced by \ (INF \) . (Of course, except for the reverse side).


Code

#include<bits/stdc++.h>
using namespace std;
const int _=60+7;
const int __=1202+7;
const int ___=3760+7;
const int inf=0x3f3f3f3f;
int n,m,S,T,a[_][_],num[_][_],dis[__],ans,cnt;
int lst[__],nxt[___],to[___],c[___],w[___],bk[___],tot=1;
bool vis[__],mst[___],cha[___];
queue<int> q;
void init(){
  cin>>m>>n;
  for(int i=1;i<=n;i++){
    for(int j=1;j<=m+i-1;j++){
      scanf("%d",&a[i][j]);
      num[i][j]=++cnt;
    }
  }
  S=(m+m+n-1)*n+1; T=S+1;
}
void add(int x,int y,int cap,int wgt){
  if(x==S) mst[tot+1]=1;
  if(y==x+cnt||y==T) cha[tot+1]=1;
  nxt[++tot]=lst[x]; to[tot]=y; c[tot]=cap; w[tot]=wgt; lst[x]=tot; bk[tot]=cap;
  nxt[++tot]=lst[y]; to[tot]=x; c[tot]=0; w[tot]=-wgt; lst[y]=tot;
}
void link(){
  for(int i=1;i<=m;i++)
    add(S,num[1][i],1,a[1][i]);
  for(int i=1;i<=m+n-1;i++)
    add(num[n][i]+cnt,T,1,0);
  for(int i=1;i<n;i++)
    for(int j=1;j<=m+i-1;j++){
      add(num[i][j]+cnt,num[i+1][j],1,a[i+1][j]);
      add(num[i][j]+cnt,num[i+1][j+1],1,a[i+1][j+1]);
    }
  for(int i=1;i<=cnt;i++)
    add(i,i+cnt,1,0);
}
bool SPFA(){
  for(int i=1;i<=T;i++){ dis[i]=-inf; vis[i]=0; }
  while(!q.empty()) q.pop();
  dis[S]=0; q.push(S);
  while(!q.empty()){
    int u=q.front(); q.pop();
    vis[u]=0;
    for(int i=lst[u];i;i=nxt[i]){
      int v=to[i];
      if(!c[i]||dis[v]>=dis[u]+w[i]) continue;
      dis[v]=dis[u]+w[i];
      if(!vis[v]){
    q.push(v);
    vis[v]=1;
      }
    }
  }
  return dis[T]!=-inf;
}
int dfs(int u,int flow){
  if(u==T) return flow;
  int rest=flow; vis[u]=1;
  for(int i=lst[u];i;i=nxt[i]){
    int v=to[i];
    if(vis[v]||!c[i]||dis[v]!=dis[u]+w[i]) continue;
    int cst=dfs(v,min(rest,c[i]));
    if(cst==0) dis[v]=-inf;
    else{
      c[i]-=cst; c[i^1]+=cst;
      rest-=cst; ans+=cst*w[i];
    }
  }
  return flow-rest;
}
void Dinic(){
  ans=0;
  int flow;
  while(SPFA())
    do{
      flow=dfs(S,inf);
    }while(flow);
}
void change(int ty){
  if(ty==2){
    for(int i=2;i<=tot;i+=2){
      if(cha[i]) c[i]=inf;
      else c[i]=bk[i];
      c[i^1]=0;
    }
  }
  else{
    for(int i=2;i<=tot;i+=2){
      if(!mst[i]) c[i]=inf;
      else c[i]=bk[i];
      c[i^1]=0;
    }
  }
}
int main(){
#ifndef ONLINE_JUDGE
  freopen("x.in","r",stdin);
#endif
  init();
  link();
  Dinic();
  printf("%d\n",ans);
  
  change(2);
  Dinic();
  printf("%d\n",ans);
  
  change(3);
  Dinic();
  printf("%d\n",ans);
  
  return 0;
}

Guess you like

Origin www.cnblogs.com/BruceW/p/12207742.html