网络流二十四题之十六 —— 数字梯形问题(DIGIT)

来源:互联网 发布:淘宝优惠券招代理 编辑:程序博客网 时间:2024/05/18 01:23

数字梯形问题


Description

给定一个由 n 行数字组成的数字梯形如下图所示。

这里写图片描述
梯形的第一行有 m 个数字。
从梯形的顶部的 m 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶
至底的路径。
规则1:从梯形的顶至底的 m 条路径互不相交。
规则2:从梯形的顶至底的 m 条路径仅在数字结点处相交。
规则3:从梯形的顶至底的 m 条路径允许在数字结点相交或边相交。

对于给定的数字梯形,分别按照规则1,规则2,和规则3 计算出从梯形的顶至底的 m条路径,使这 m 条路径经过的数字总和最大。


Input

1 行中有 2 个正整数 mnm,n<=20),分别表示数字梯形的第一行有 m 个数字,共有 n 行。
接下来的 n 行是数字梯形中各行的数字。
1 行有 m 个数字,第 2 行有 m+1 个数字,…。


Output

将按照规则1,规则2,和规则3计算出的最大数字总和输出。
每行一个最大总和。


Sample Input

2 5
2 3
3 4 5
9 10 9 1
1 1 10 1 1
1 1 10 12 1 1


Sample Output

66
75
77


Solution

很简单的费用流题目——只要拆点就可以了。


Code

[cpp]
  1. #include <iostream>  
  2. #include <cstdio>  
  3. #include <queue>  
  4. #include <cstring>  
  5.   
  6. #define PLA(x,y) PLA[(x)][(y)]  
  7. #define Min(x,y) ((x)<(y)?(x):(y))  
  8. #define Max(x,y) ((x)>(y)?(x):(y))  
  9. #define ANOTHER 2000  
  10. #define INF 0x3f3f3f3f  
  11. #define ss 0    
  12. #define tt 5000  
  13.   
  14. using namespace std;  
  15.   
  16. int n,m,tmp,ans,cnt;  
  17.   
  18. int maps[100][100];  
  19. int f[100][100];  
  20. int head[10010],nxt[1000100],wei[1000100],flow[1000100],data[1000100];  
  21. int PLA[1000][1000];  
  22. int dis[10010];  
  23. int pre[10010];  
  24. bool in_stack[10010];   
  25. queue<int>q;  
  26.   
  27. void add(int x,int y,int a,int b){  
  28.     nxt[cnt]=head[x];data[cnt]=y;wei[cnt]=b;flow[cnt]=a;head[x]=cnt++;      
  29.     nxt[cnt]=head[y];data[cnt]=x;wei[cnt]=-b;flow[cnt]=0;head[y]=cnt++;   
  30. }  
  31.   
  32. bool BFS(){  
  33.     memset(dis,0x3f,sizeof dis);dis[ss]=0;in_stack[ss]=true;q.push(ss);pre[ss]=pre[tt]=-1;  
  34.     while(!q.empty()){  
  35.         int now=q.front();  
  36.         q.pop();  
  37.         in_stack[now]=false;  
  38.         for(int i=head[now];i!=-1;i=nxt[i]){  
  39.             if(flow[i]!=0&&dis[data[i]]>dis[now]+wei[i]){  
  40.                 dis[data[i]]=dis[now]+wei[i];  
  41.                 pre[data[i]]=i^1;  
  42.                 if(!in_stack[data[i]]){  
  43.                     in_stack[data[i]]=true;  
  44.                     q.push(data[i]);  
  45.                 }  
  46.             }  
  47.         }  
  48.     }  
  49.     return pre[tt]!=-1;  
  50. }  
  51.   
  52. void dfs(){  
  53.     int Low=INF;  
  54.     for(int i=pre[tt];i!=-1;i=pre[data[i]])Low=Min(Low,flow[i^1]);  
  55.     for(int i=pre[tt];i!=-1;i=pre[data[i]])flow[i^1]-=Low,flow[i]+=Low;   
  56.     ans+=Low*dis[tt];  
  57. }  
  58.   
  59. int main(){  
  60.       
  61.     freopen(”digit.in”,“r”,stdin);  
  62.     freopen(”digit.out”,“w”,stdout);  
  63.       
  64.     memset(head,-1,sizeof head);  
  65.       
  66.     scanf(”%d%d”,&m,&n);tmp=m;  
  67.       
  68.     int tot=0;   
  69.     for(int i=1;i<=n;i++,tmp++)  
  70.         for(int j=1;j<=tmp;j++)  
  71.             PLA[i][j]=++tot;  
  72.     tmp=m;  
  73.     for(int i=1;i<=n;i++,tmp++)  
  74.         for(int j=1;j<=tmp;j++){  
  75.             scanf(”%d”,&maps[i][j]);  
  76.             if(i!=n){  
  77.                 add(PLA(i,j),PLA(i+1,j)+ANOTHER,1,0);  
  78.                 add(PLA(i,j),PLA(i+1,j+1)+ANOTHER,1,0);  
  79.             }  
  80.         }  
  81.           
  82.     for(int i=1;i<=n+m-1;i++)add(PLA(n,i),tt,1,0);  
  83.     for(int i=1;i<=m;i++)add(ss,PLA(1,i)+ANOTHER,1,0);  
  84.       
  85.     tmp=m;  
  86.     for(int i=1;i<=n;i++,tmp++)  
  87.         for(int j=1;j<=tmp;j++)  
  88.             add(PLA(i,j)+ANOTHER,PLA(i,j),1,-maps[i][j]);  
  89.       
  90.     while(BFS())dfs();  
  91.     printf(”%d\n”,-ans);   
  92.       
  93.     memset(head,-1,sizeof head);  
  94.     cnt=0;  
  95.       
  96.     for(int i=1;i<=m;i++)add(ss,PLA(1,i),1,0);  
  97.     for(int i=1;i<=n+m-1;i++)add(PLA(n,i),tt,INF,-maps[n][i]);  
  98.       
  99.     tmp=m;  
  100.     for(int i=1;i<=n;i++,tmp++)  
  101.         for(int j=1;j<=tmp;j++){  
  102.             if(i!=n){  
  103.                 add(PLA(i,j),PLA(i+1,j),1,-maps[i][j]);  
  104.                 add(PLA(i,j),PLA(i+1,j+1),1,-maps[i][j]);  
  105.             }  
  106.         }  
  107.     ans=0;  
  108.     while(BFS())  
  109.     dfs();  
  110.     printf(”%d\n”,-ans);  
  111.       
  112.     ans=0;  
  113.     tmp=n+m-2;  
  114.       
  115.     for(int i=1;i<=tmp+1;i++)f[n][i]=maps[n][i];  
  116.     for(int i=n-1;i>=1;i–,tmp–)  
  117.         for(int j=1;j<=tmp;j++)  
  118.             f[i][j]=Max(f[i+1][j],f[i+1][j+1])+maps[i][j];  
  119.     for(int i=1;i<=m;i++)ans+=f[1][i];  
  120.     printf(”%d\n”,ans);  
  121.       
  122.     return 0;  
  123. }  
0 0