LOJ #6010. 「网络流 24 题」数字梯形

#6010. 「网络流 24 题」数字梯形

 

题目描述

给定一个由 n nn 行数字组成的数字梯形如下图所示。梯形的第一行有 m mm 个数字。从梯形的顶部的 m mm 个数字开始,在每个数字处可以沿左下或右下方向移动,形成一条从梯形的顶至底的路径。

分别遵守以下规则:

  1. 从梯形的顶至底的 m mm 条路径互不相交;
  2. 从梯形的顶至底的 m mm 条路径仅在数字结点处相交;
  3. 从梯形的顶至底的 m mm 条路径允许在数字结点相交或边相交。

输入格式

第 1 11 行中有 2 22 个正整数 m mm 和 n nn,分别表示数字梯形的第一行有 m mm 个数字,共有 n nn 行。接下来的 n nn 行是数字梯形中各行的数字。
第 1 11 行有 m mm 个数字,第 2 22 行有 m+1 m + 1m+1 个数字 ……

输出格式

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

样例

样例输入

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

样例输出

66
75
77

数据范围与提示

1≤m,n≤20 1 \leq m, n \leq 201m,n20

 

code

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 
  5 using namespace std;
  6 const int N = 1010;
  7 const int INF = 1e9;
  8 
  9 struct Edge{
 10     int u,v,f,c,nxt;
 11     Edge(){}
 12     Edge(int a,int b,int flow,int cost,int nt) {
 13         u = a;v = b;f = flow;c = cost;nxt = nt;
 14     }
 15 }e[100100];
 16 int head[N],dis[N],q[100100],pre[N],a[30][30],b[30][30];
 17 bool vis[N];
 18 int n,m,S,T,tn,L,R,Mc,ans,tot;
 19 
 20 inline char nc() {
 21     static char buf[100000],*p1 = buf,*p2 = buf;
 22     return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2) ? EOF :*p1++;
 23 }
 24 inline int read() {
 25     int x = 0,f = 1;char ch=nc();
 26     for (; ch<'0'||ch>'9'; ch=nc()) if(ch=='-')f=-1;
 27     for (; ch>='0'&&ch<='9'; ch=nc()) x=x*10+ch-'0';
 28     return x*f;
 29 }
 30 void add_edge(int u,int v,int f,int c) {
 31     e[++tot] = Edge(u,v,f,c,head[u]);head[u] = tot;
 32     e[++tot] = Edge(v,u,0,-c,head[v]);head[v] = tot;
 33 }
 34 bool spfa() {
 35     for (int i=1; i<=T; ++i) vis[i]=false,dis[i]=INF;
 36     L = 1;R = 0;
 37     dis[S] = 0;
 38     q[++R] = S;vis[S] = true;pre[S] = 0;
 39     while (L <= R) {
 40         int u = q[L++];
 41         for (int i=head[u]; i; i=e[i].nxt) {
 42             int v = e[i].v;
 43             if (dis[v]>dis[u]+e[i].c && e[i].f > 0) {
 44                 dis[v] = dis[u] + e[i].c;
 45                 pre[v] = i;
 46                 if (!vis[v]) q[++R] = v,vis[v] = true;
 47             }
 48         }
 49         vis[u] = false;
 50     }
 51     return dis[T]!=INF;
 52 }
 53 void mcf() {
 54     int zf = INF;
 55     for (int i=T; i!=S; i=e[pre[i]].u) 
 56         zf = min(zf,e[pre[i]].f);
 57     for (int i=T; i!=S; i=e[pre[i]].u) 
 58         e[pre[i]].f -= zf,e[pre[i]^1].f += zf;
 59     Mc += dis[T]*zf;
 60 }
 61 int work() {
 62     Mc = 0;
 63     while (spfa()) mcf();
 64     printf("%d\n",-Mc);
 65 }
 66 void init() {
 67     tot = 1;
 68     memset(head,0,sizeof(head));
 69 }
 70 void build_1() {
 71     init();
 72     S = tn + tn + 1;T = tn + tn + 2;
 73     for (int i=1; i<=n; ++i) 
 74         for (int j=1; j<=m+i-1; ++j) {
 75             add_edge(b[i][j],b[i][j]+tn,1,-a[i][j]);
 76             add_edge(b[i][j]+tn,b[i+1][j],1,0);
 77             add_edge(b[i][j]+tn,b[i+1][j+1],1,0);
 78             if (i==1) add_edge(S,b[i][j],1,0);
 79             if (i==n) add_edge(b[i][j]+tn,T,1,0);
 80         }
 81 }
 82 void build_2() {
 83     init();
 84     S = tn + 1;T = tn + 2;
 85     for (int i=1; i<=n; ++i) {
 86         for (int j=1; j<=m+i-1; ++j) {
 87             add_edge(b[i][j],b[i+1][j],1,-a[i][j]);
 88             add_edge(b[i][j],b[i+1][j+1],1,-a[i][j]);
 89             if (i==1) add_edge(S,b[i][j],1,0);
 90             if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
 91         }
 92     }
 93 }
 94 void build_3() {
 95     init();
 96     S = tn + 1;T = tn + 2;
 97     for (int i=1; i<=n; ++i) {
 98         for (int j=1; j<=m+i-1; ++j) {
 99             add_edge(b[i][j],b[i+1][j],INF,-a[i][j]);
100             add_edge(b[i][j],b[i+1][j+1],INF,-a[i][j]);
101             if (i==1) add_edge(S,b[i][j],1,0);
102             if (i==n) add_edge(b[i][j],T,INF,-a[i][j]);
103         }
104     }
105 }
106 int main() {
107     m = read(),n = read();
108     for (int i=1; i<=n; ++i) 
109         for (int j=1; j<=m+i-1; ++j) a[i][j] = read(),b[i][j] = ++tn;
110 
111     build_1();work();
112     build_2();work();
113     build_3();work();
114     return 0;
115 }

 

posted @ 2018-03-10 22:04  MJT12044  阅读(301)  评论(0编辑  收藏  举报