zoukankan      html  css  js  c++  java
  • [网络流最大流经典][uva 11082][矩阵解压]

    题目大意

    这里写图片描述

    分析

    这里写图片描述

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <algorithm>
    #include <iostream>
    #include <sstream>
    #include <string>
    #define oo 0x13131313
    using namespace std;
    const int MAXN=200+5;
    const int MAXM=2000;
    const int INF=0x3f3f3f3f;
    struct Edge
    {
        int to,next,cap,flow;
        void get(int a,int b,int c,int d)
        {
            to=a;next=b;cap=c;flow=d;
        }
    }edge[MAXM];
    int tol;
    int head[MAXN];
    int gap[MAXN],dep[MAXN],pre[MAXN],cur[MAXN];
    void init()
    {
        tol=0;
        memset(head,-1,sizeof(head));
    }
    //单向图三个参数,无向图四个参数
    void addedge(int u,int v,int w,int rw=0)
    {
        edge[tol].get(v,head[u],w,0);head[u]=tol++;
        edge[tol].get(u,head[v],rw,0);head[v]=tol++;
    }
    int sap(int start,int end,int N)
    {
        memset(gap,0,sizeof(gap));
        memset(dep,0,sizeof(dep));
        memcpy(cur,head,sizeof(head));
        int u=start;
        pre[u]=-1;
        gap[0]=N;
        int ans=0;
        while(dep[start]<N)
        {
            if(u==end)
            {
                int Min=INF;
                for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                    if(Min>edge[i].cap-edge[i].flow)
                       Min=edge[i].cap-edge[i].flow;
                for(int i=pre[u];i!=-1;i=pre[edge[i^1].to])
                {
                    edge[i].flow+=Min;
                    edge[i^1].flow-=Min;
                }
                u = start;
                ans+=Min;
                continue;
            }
            bool flag=false;
            int v;
            for(int i=cur[u];i !=-1;i=edge[i].next)
            {
                v=edge[i].to;
                if(edge[i].cap-edge[i].flow&&dep[v]+1==dep[u])
                {
                    flag=true;
                    cur[u]=pre[v]=i;
                    break;
                }
            }
            if(flag)
            {
                u=v;
                continue;
            }
            int Min=N;
            for(int i=head[u];i!=-1;i=edge[i].next)
                if(edge[i].cap-edge[i].flow&&dep[edge[i].to]<Min)
            {
                Min=dep[edge[i].to];
                cur[u]=i;
            }
            gap[dep[u]]--;
            if(!gap[dep[u]]) return ans;
            dep[u]=Min+1;
            gap[dep[u]]++;
            if(u!=start) u=edge[pre[u]^1].to;
        }
        return ans;
    }
    int R,C;
    int A[50],B[50];
    int ANS[50][50];
    int sum=0; 
    void input()
    {
        sum=0;
        init();
        cin>>R>>C;
        for(int i=1;i<=R;i++)
        scanf("%d",&A[i]);
        for(int i=1;i<=C;i++)
        scanf("%d",&B[i]);
        for(int i=R;i>=1;i--)
        {
        A[i]=A[i]-A[i-1];
        sum=sum+A[i];
        }
        for(int i=C;i>=1;i--)
        B[i]=B[i]-B[i-1];
    }
    void solve()
    {
        int S=0,T=R+C+1;
        //S->
        for(int i=1;i<=R;i++)
        {
            addedge(S,i,A[i]-C);
        }
        //->T 
        for(int i=1;i<=C;i++)
        {
            addedge(R+i,T,B[i]-R);
        }
        for(int i=1;i<=R;i++)
            for(int j=1;j<=C;j++)
            {
                addedge(i,R+j,19);
            }
    }
    int main()
    {
    //  freopen("a.in","r",stdin);
        int T;
        cin>>T;
        int CASE=0;
        while(T--)
        {
            printf("Matrix %d
    ",++CASE);
            input();
            solve();
            int k=sap(0,R+C+1,R+C+2);
            for(int i=1;i<=R;i++)
            {
                for(int p=head[i];p!=-1;p=edge[p].next)
                {
                    ANS[i][edge[p].to-R]=edge[p].flow+1; 
                }
            }
            for(int i=1;i<=R;i++)
                {
                    for(int j=1;j<=C;j++)
                    {
                        printf("%d",ANS[i][j]);
                        if(j!=C) printf(" ");
                    }
                    printf("
    ");
                } 
            printf("
    "); 
        }
    
    }
  • 相关阅读:
    LOJ3160 「NOI2019」斗主地
    常系数齐次线性递推
    最小树形图——朱刘算法学习小记
    Linux系统分区(一)
    Linux系统启动过程(二)
    Linux系统目录结构(三)
    cross_val_score
    sklearn.pipeline.Pileline
    DBSCAN密度聚类算法
    特征选择
  • 原文地址:https://www.cnblogs.com/zy691357966/p/5480305.html
Copyright © 2011-2022 走看看