HDOJ 2686 - Matrix & HDOJ 3376 - Matrix Again 构图最小费用最大流 or dp

来源:互联网 发布:python数字识别 编辑:程序博客网 时间:2024/05/21 22:57

                    题意:

                             给一个矩阵..问从左上角走到右下角..再从右下角走回左上角..不经过重复的点并且从左上至至右下时只能向右或者向下走,从右下至左上时只能向上或者左走..经过一个点..加上它的值...问能取到的最大值是多少...

                    题解:

                             这题和曾经一道Noip的差不多...可以用三维的DP...也可以用最小费用最大流...为了限制点经过次数..必须拆点..注意的是起点和终点会经过两次..所以拆点后这两个点间的容量为2....


Program:

#include<iostream>  #include<algorithm>  #include<stdio.h>  #include<string.h>  #include<math.h>  #include<queue>  #define MAXN 5005  #define MAXM 500005  #define oo 1000000007  #define ll long long  using namespace std;    struct MCMF    {           struct node           {                  int x,y,c,v,next;            }line[MAXM];           int Lnum,_next[MAXN],pre[MAXN],dis[MAXN],flow,cost;           bool inqueue[MAXN];           void initial(int n)           {                  Lnum=-1;                  for (int i=0;i<=n;i++) _next[i]=-1;           }           void addline(int x,int y,int c,int v)           {                  line[++Lnum].next=_next[x],_next[x]=Lnum;                  line[Lnum].x=x,line[Lnum].y=y,line[Lnum].c=c,line[Lnum].v=v;                  line[++Lnum].next=_next[y],_next[y]=Lnum;                  line[Lnum].x=y,line[Lnum].y=x,line[Lnum].c=0,line[Lnum].v=-v;           }           bool SPFA(int s,int e)           {                  int x,k,y;                  queue<int> Q;                  while (!Q.empty()) Q.pop();                  memset(dis,0x7f,sizeof(dis));                  memset(inqueue,false,sizeof(inqueue));                  Q.push(s);                  dis[s]=0,pre[s]=-1;                  while (!Q.empty())                  {                          x=Q.front(),Q.pop(),inqueue[x]=false;                          for (k=_next[x];k!=-1;k=line[k].next)                               if (line[k].c)                             {                                   y=line[k].y;                                   if (dis[y]>dis[x]+line[k].v)                                   {                                            dis[y]=dis[x]+line[k].v;                                            pre[y]=k;                                            if (!inqueue[y])                                            {                                                    inqueue[y]=true;                                                    Q.push(y);                                            }                                   }                             }                  }                  if (dis[e]>oo) return false;                  flow=oo,cost=0;                  for (k=pre[e];k!=-1;k=pre[line[k].x])                       flow=min(flow,line[k].c),cost+=line[k].v;                      cost*=flow;                  for (k=pre[e];k!=-1;k=pre[line[k].x])                      line[k].c-=flow,line[k^1].c+=flow;                    return true;           }           void MinCostMaxFlow(int s,int e,int &Aflow,int &Acost)           {                  Aflow=0,Acost=0;                  while (SPFA(s,e))                  {                         Aflow+=flow;                         Acost+=cost;                   }                }    }T;     int A[35][35];int main() {                    int n,i,j,x,h,hh,s,e,Ac;        while (~scanf("%d",&n))      {              s=0,e=n*n-1,T.initial(e<<2);              for (i=0;i<n;i++)                for (j=0;j<n;j++)                {                       scanf("%d",&x),h=i*n+j;                       T.addline(h<<1,h<<1|1,1,-x);                       if (i!=n-1) hh=h+n,T.addline(h<<1|1,hh<<1,1,0);                       if (j!=n-1) hh=h+1,T.addline(h<<1|1,hh<<1,1,0);                }              T.addline(s<<1,s<<1|1,1,0),T.addline(e<<1,e<<1|1,1,0);              s=s<<1,e=e<<1|1;              T.MinCostMaxFlow(s,e,x,Ac);              printf("%d\n",-Ac);      }      return 0;}


原创粉丝点击