首页 > 其他 > 详细

洛谷 P4013 数字梯形问题

时间:2018-08-07 12:36:54      阅读:156      评论:0      收藏:0      [点我收藏+]

->题目链接

 

技术分享图片

技术分享图片

题解:

网络流。

技术分享图片
#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
#define N 4010
#define inf 1000000000
using namespace std;
int a[N][N],head[N],dis[N],inq[N],fa[N],n,m,num,cnt,S,T;
struct node {
    int u,v,pre,f,w;
} e[N];
void add(int u,int v,int f,int w) {
    e[++cnt].u=u;e[cnt].v=v;
    e[cnt].f=f;e[cnt].w=w;
    e[cnt].pre=head[u];head[u]=cnt;
    e[++cnt].u=v;e[cnt].v=u;
    e[cnt].f=0;e[cnt].w=-w;
    e[cnt].pre=head[v];head[v]=cnt;
}
bool spfa() {
    for(int i=0; i<=T; i++) dis[i]=inf;
    queue<int> q;
    q.push(S);
    inq[S]=1;
    dis[S]=0;
    while(!q.empty()) {
        int u=q.front();
        q.pop();
        inq[u]=0;
        for(int i=head[u]; i; i=e[i].pre)
            if(e[i].f&&dis[e[i].v]>dis[u]+e[i].w) {
                dis[e[i].v]=dis[u]+e[i].w;
                fa[e[i].v]=i;
                if(!inq[e[i].v]) {
                    inq[e[i].v]=1;
                    q.push(e[i].v);
                }
            }
    }
    return dis[T]!=inf;
}
void mincost() {
    int cost=0;
    while(spfa()) {
        int tmp=fa[T],x=inf;
        while(tmp) {
            int u=e[tmp].u;
            x=min(x,e[tmp].f);
            tmp=fa[e[tmp].u];
        }
        tmp=fa[T];
        while(tmp) {
            e[tmp].f-=x;
            e[tmp^1].f+=x;
            tmp=fa[e[tmp].u];
        }
        cost+=x*dis[T];
    }
    printf("%d\n",-cost);
}
int hao(int i,int j) {
    return (m*2+i-2)*(i-1)/2+j;
}
void build1() {
    cnt=1;
    memset(head,0,sizeof(head));
    for(int i=1; i<=m; i++)
        add(S,i,1,-a[1][i]);
    for(int i=1; i<n; i++)
        for(int j=1; j<=m+i-1; j++)
            add(hao(i,j)+num,hao(i+1,j),1,-a[i+1][j]),add(hao(i,j)+num,hao(i+1,j+1),1,-a[i+1][j+1]);
    for(int i=1; i<=m+n-1; i++)
        add(hao(n,i)+num,T,1,0);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m+i-1; j++)
            add(hao(i,j),hao(i,j)+num,1,0);

}
void build2() {
    cnt=1;
    memset(head,0,sizeof(head));
    for(int i=1; i<=m; i++)
        add(S,i,1,-a[1][i]);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m+i-1; j++)
            add(hao(i,j),hao(i+1,j),1,-a[i+1][j]),add(hao(i,j),hao(i+1,j+1),1,-a[i+1][j+1]);
    for(int i=1; i<=m+n-1; i++)
        add(hao(n,i),T,inf,0);
}
void build3() {
    cnt=1;
    memset(head,0,sizeof(head));
    for(int i=1; i<=m; i++)
        add(S,i,1,-a[1][i]);
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m+i-1; j++)
            add(hao(i,j),hao(i+1,j),inf,-a[i+1][j]),add(hao(i,j),hao(i+1,j+1),inf,-a[i+1][j+1]);
    for(int i=1; i<=m+n-1; i++)
        add(hao(n,i),T,inf,0);
}
int main() {
    scanf("%d%d",&m,&n);
    num=(m*2+n-1)*n/2;
    S=0;
    T=num*2+1;
    for(int i=1; i<=n; i++)
        for(int j=1; j<=m+i-1; j++)
            scanf("%d",&a[i][j]);
    build1();
    mincost();
    build2();
    mincost();
    build3();
    mincost();
    return 0;
}  
AC

我走我的独木桥。

洛谷 P4013 数字梯形问题

原文:https://www.cnblogs.com/GTBD/p/9435890.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!