1 条题解

  • 0
    @ 2023-6-21 19:57:31

    C++ :

    #pragma comment(linker, "/STACK:102400000,102400000")
    #include <map>
    #include <set>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <string>
    #include <vector>
    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <sstream>
    #include <cstdlib>
    #include <iostream>
    #include <algorithm>
    #define MOD 1e9+7
    #define lson l,mid,root<<1
    #define rson mid+1,r,root<<1|1
    #define DBN1(a)           cerr<<#a<<"="<<(a)<<"\n"
    #define DBN2(a,b)         cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<"\n"
    #define DBN3(a,b,c)       cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<"\n"
    #define DBN4(a,b,c,d)     cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<"\n"
    #define DBN5(a,b,c,d,e)   cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<"\n"
    #define DBN6(a,b,c,d,e,f) cerr<<#a<<"="<<(a)<<", "<<#b<<"="<<(b)<<", "<<#c<<"="<<(c)<<", "<<#d<<"="<<(d)<<", "<<#e<<"="<<(e)<<", "<<#f<<"="<<(f)<<"\n"
    using namespace std;
    typedef long long ll;
    const int maxn=20*20+5;
    const int INF=0x3f3f3f3f;
    const double PI=acos(-1.0);
    template<typename T>
    inline T read(T&x){
        x=0;int _f=0;char ch=getchar();
        while(ch<'0'||ch>'9')_f|=(ch=='-'),ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x=_f?-x:x;
    }
    struct Edge{
        int from,to,cap,flow,cost;
        Edge(){}
        Edge(int f,int t,int c,int fl,int co):from(f),to(t),cap(c),flow(fl),cost(co){}
    };
    
    struct MCMF{
        int n,m,s,t,k;
        vector<Edge> edges;
        vector<int> G[maxn];
        bool inq[maxn];
        int d[maxn];
        int p[maxn];
        int a[maxn];
    
        void init(int n,int s,int t){
            this->n=n, this->s=s, this->t=t;
            edges.clear();
            for(int i=0;i<=n;++i) G[i].clear();
        }
    
        void AddEdge(int from,int to,int cap,int cost){
            edges.push_back(Edge(from,to,cap,0,cost));
            edges.push_back(Edge(to,from,0,0,-cost));
            m=edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        bool SPFA(int &flow,int &cost){
            for(int i=0;i<n;++i) d[i]=INF;
            queue<int>Q;
            memset(inq,0,sizeof(inq));
            d[s]=0, Q.push(s), a[s]=INF, p[s]=0, inq[s]=true;
            while(!Q.empty()){
                int u=Q.front(); Q.pop();
                inq[u]=false;
                for(int i=0;i<(int)G[u].size();++i){
                    Edge &e=edges[G[u][i]];
                    if(e.cap>e.flow && d[e.to]>d[u]+e.cost){
                        d[e.to]=d[u]+e.cost;
                        p[e.to]=G[u][i];
                        a[e.to]=min(a[u],e.cap-e.flow);
                        if(!inq[e.to]){ Q.push(e.to); inq[e.to]=true; }
                    }
                }
            }
            if(d[t]==INF) return false;
            flow+=a[t];
            int u=t;
            while(u!=s){
                edges[p[u]].flow+=a[t];
                edges[p[u]^1].flow-=a[t];
                cost+=a[t]*edges[p[u]].cost;
                u=edges[p[u]].from;
            }
            return true;
        }
    
        int solve(){
            int flow=0,cost=0;
            while(SPFA(flow,cost));
            return cost;
        }
    }MM;
    int a[maxn][maxn];
    int id[maxn][maxn],idx;
    int m,n;
    void solve1(){
        MM.init(idx*2+2,0,idx*2+1);
        for (int i=1;i<=m;i++){
            MM.AddEdge(0,id[1][i],1,0);
        }
        for (int i=1;i<=n+m-1;i++){
            MM.AddEdge(id[n][i]+idx,idx*2+1,1,0);
        }
        for (int i=1;i<=n;i++){
            for (int j=1;j<=m+i-1;j++){
                MM.AddEdge(id[i][j],id[i][j]+idx,1,-a[i][j]);
                if (i!=n){
                    MM.AddEdge(id[i][j]+idx,id[i+1][j],1,0);
                    MM.AddEdge(id[i][j]+idx,id[i+1][j+1],1,0);
                }
            }
        }
        printf("%d\n",(-1)*MM.solve());
    }
    void solve2(){
        MM.init(idx+2,0,idx+1);
        for (int i=1;i<=m;i++) MM.AddEdge(0,id[1][i],1,0);
        for (int i=1;i<=n+m-1;i++) MM.AddEdge(id[n][i],idx+1,INF,-a[n][i]);
        for (int i=1;i<n;i++){
            for (int j=1;j<=m+i-1;j++){
                MM.AddEdge(id[i][j],id[i+1][j],1,-a[i][j]);
                MM.AddEdge(id[i][j],id[i+1][j+1],1,-a[i][j]);
            }
        }
        printf("%d\n",(-1)*MM.solve());
    }
    void solve3(){
        MM.init(idx+2,0,idx+1);
        for (int i=1;i<=m;i++) MM.AddEdge(0,id[1][i],1,0);
        for (int i=1;i<=n+m-1;i++) MM.AddEdge(id[n][i],idx+1,INF,-a[n][i]);
        for (int i=1;i<n;i++){
            for (int j=1;j<=m+i-1;j++){
                MM.AddEdge(id[i][j],id[i+1][j],INF,-a[i][j]);
                MM.AddEdge(id[i][j],id[i+1][j+1],INF,-a[i][j]);
            }
        }
        printf("%d\n",(-1)*MM.solve());
    }
    int main(){
        read(m),read(n);
        idx=0;
        for (int i=1;i<=n;i++){
            for (int j=1;j<=m+i-1;j++){
                read(a[i][j]);
                id[i][j]=++idx;
            }
        }
        solve1();
        solve2();
        solve3();
        return 0;
    }
    
    • 1

    信息

    ID
    998
    时间
    1000ms
    内存
    256MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者