[网络流24题] 数字梯形问题

Posted Orion545

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[网络流24题] 数字梯形问题相关的知识,希望对你有一定的参考价值。

题面:

传送门

思路:

三合一题目

但是实际上做好了第一个就没有别的问题了

第一问:

把每个数字拆成两个点,中间连一条容量为1,费用为0的边,以此达到限制每个点流量的目的

然后其余的不多说,源点到第一层,每一层向下连,最后一层到汇点

第二问:

第一问中每个点内部的那条边容量改成inf就好

第三问:

直接dp算了......当然你也可以再改改边,跑网络流,不过估计没有dp快

Code:

  1     #include<iostream>
  2     #include<cstdio>
  3     #include<cstring>
  4     #include<algorithm>
  5     #define inf 1000000000
  6     using namespace std;
  7     inline int read(){
  8         int re=0,flag=1;char ch=getchar();
  9         while(ch>9||ch<0){
 10             if(ch==-) flag=-1;
 11             ch=getchar();
 12         }
 13         while(ch>=0&&ch<=9) re=(re<<1)+(re<<3)+ch-0,ch=getchar();
 14         return re;
 15     }
 16     int n,m,cnt,ans,flow,tot,first[10010],x[25][25],id[25][25];
 17     int dis[10010],pre[10010],path[10010];
 18     struct edge{
 19         int to,next,w,cap;
 20     }a[100010];
 21     inline void add(int u,int v,int w,int cap){
 22     //    cout<<"add "<<u<<ends<<v<<ends<<w<<ends<<cap<<endl;
 23         a[++cnt]=(edge){v,first[u],w,cap};first[u]=cnt;
 24         a[++cnt]=(edge){u,first[v],-w,0};first[v]=cnt;
 25     }
 26     void init(){
 27         memset(first,-1,sizeof(first));
 28         memset(a,0,sizeof(a));cnt=-1;ans=0;flow=0;
 29     }
 30     int spfa(int s,int t){
 31         int q[10010],head=0,tail=1,maxn=10000,i,u,v,w;
 32         memset(pre,-1,sizeof(pre));
 33         for(i=s;i<=t;i++) dis[i]=inf;
 34         q[0]=s;dis[s]=0;
 35         while(head!=tail){
 36             u=q[head];head=(head+1)%maxn;
 37     //        cout<<"spfa "<<u<<endl;
 38             for(i=first[u];~i;i=a[i].next){
 39                 v=a[i].to;w=a[i].w;
 40     //            cout<<"    to "<<v<<ends<<dis[v]<<ends<<w+dis[u]<<endl;
 41                 if(a[i].cap&&dis[v]>dis[u]+w){
 42                     dis[v]=dis[u]+w;
 43                     pre[v]=u;path[v]=i;
 44                     q[tail]=v;tail=(tail+1)%maxn;
 45                 }
 46             }
 47         }
 48         return ~pre[t];
 49     }
 50     inline int _min(int l,int r){return (l<r)?l:r;}
 51     int mcmf(int s,int t){
 52         int f,u;
 53         while(spfa(s,t)){
 54             f=inf;
 55             for(u=t;u!=s;u=pre[u]) f=_min(f,a[path[u]].cap);
 56             flow+=f;ans+=dis[t]*f;
 57     //        cout<<"mcmf "<<flow<<ends<<ans<<endl;
 58             for(u=t;u!=s;u=pre[u]){
 59                 a[path[u]].cap-=f;
 60                 a[path[u]^1].cap+=f;
 61             }
 62         }
 63     }
 64     int main(){
 65         freopen("digit.in","r",stdin);
 66         freopen("digit.out","w",stdout);
 67         int i,j;
 68         n=read();m=read();
 69         for(i=1;i<=m;i++){
 70             for(j=1;j<=i+n-1;j++) x[i][j]=read(),id[i][j]=++tot;
 71         }
 72         //T1
 73         init();
 74         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
 75         for(i=1;i<=m;i++){
 76             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,1);
 77         }
 78         for(i=1;i<m;i++){
 79             for(j=1;j<=i+n-1;j++){
 80                 add(id[i][j]+tot,id[i+1][j],-x[i][j],1);
 81                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1);
 82             }
 83         }
 84         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],1);
 85         mcmf(0,(tot<<1)+1);
 86         printf("%d\n",-ans);
 87         //T2
 88         init();
 89         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
 90         for(i=1;i<=m;i++){
 91             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf);
 92         }
 93         for(i=1;i<m;i++){
 94             for(j=1;j<=i+n-1;j++){
 95                 add(id[i][j]+tot,id[i+1][j],-x[i][j],1);
 96                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],1);
 97             }
 98         }
 99         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf);
100         mcmf(0,(tot<<1)+1);
101         printf("%d\n",-ans);
102         //T3
103         init();
104         for(i=1;i<=n;i++) add(0,id[1][i],0,1);
105         for(i=1;i<=m;i++){
106             for(j=1;j<=i+n-1;j++) add(id[i][j],id[i][j]+tot,0,inf);
107         }
108         for(i=1;i<m;i++){
109             for(j=1;j<=i+n-1;j++){
110                 add(id[i][j]+tot,id[i+1][j],-x[i][j],inf);
111                 add(id[i][j]+tot,id[i+1][j+1],-x[i][j],inf);
112             }
113         }
114         for(i=1;i<=n+m-1;i++) add(id[m][i]+tot,(tot<<1)+1,-x[m][i],inf);
115         mcmf(0,(tot<<1)+1);
116         printf("%d",-ans);
117     }

 

以上是关于[网络流24题] 数字梯形问题的主要内容,如果未能解决你的问题,请参考以下文章

[网络流24题] 16.数字梯形问题 解题报告 (最大费用最大流)

[网络流24题] 数字梯形问题

「网络流 24 题」数字梯形

网络流24题(wll24)

网络流24题(好大的坑啊)

「网络流24题」最长不下降子序列问题