zoukankan      html  css  js  c++  java
  • UVA11082 Matrix Decompressing 最大流建模解矩阵,经典

    /**
    题目:UVA11082 Matrix Decompressing
    链接:https://vjudge.net/problem/UVA-11082
    题意:lrj入门经典P374
    已知一个矩阵的行数为r,列数为c,前i行的和ai(1<=i<=r),前j列的和bj(1<=j<=c)。
    ai,bj都在[1,20]内。求出这个矩阵。
    
    思路:通过前i行的和以及前j列的和,获得每一行的和以及每一列的和。
    
    把每一行看做一个节点,每一列看做一个节点。
    建立一个源点到达每一行。
    建立一个汇点,每一列到达汇点。
    每一行到达每一列。
    
    由于数据范围是[1,20]。流可以说0.所以为了方便处理,所有容量-1.最后结果+1.
    那么源点到第i行的容量为r[i]-列数。(每一行有列数个数)
    第j列到汇点的容量为c[j]-行数。
    第i行到第j列的容量都为19。(20-1)
    
    每一行都经过每一列组成。所以这样建立连接。
    
    如果源点到每一个行节点都是满载。
    每一个列节点到汇点都是满载。
    那么有解。
    
    解为:
    第i行第j列的元素为第i行的节点到第j列的节点的流+1。
    
    */
    #include<iostream>
    #include<cstring>
    #include<vector>
    #include<map>
    #include<cstdio>
    #include<algorithm>
    #include<queue>
    using namespace std;
    const int INF = 0x3f3f3f3f;
    typedef long long LL;
    const int N = 110;
    int r[N], c[N];
    struct Edge{
        int from, to, cap, flow;
        Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
    };
    struct EdmondsKarp
    {
        int n, m;
        vector<Edge> edges;
        vector<int> G[N];
        int p[N];
        int a[N];
        int ans[N][N];
    
        void init(int n)
        {
            for(int i = 0; i <= n; i++) G[i].clear();
            edges.clear();
        }
        void AddEdge(int from,int to,int cap){
            edges.push_back((Edge){from,to,cap,0});
            edges.push_back((Edge){to,from,0,0});
            m = edges.size();
            G[from].push_back(m-2);
            G[to].push_back(m-1);
        }
    
        int Maxflow(int s,int t)
        {
            int flow = 0;
            for(;;){
                memset(a, 0, sizeof a);
                queue<int>Q;
                Q.push(s);
                a[s] = INF;
                while(!Q.empty()){
                    int x = Q.front(); Q.pop();
                    for(int i = 0; i < G[x].size(); i++){
                        Edge& e = edges[G[x][i]];
                        if(!a[e.to]&&e.cap>e.flow){
                            p[e.to] = G[x][i];
                            a[e.to] = min(a[x],e.cap-e.flow);
                            Q.push(e.to);
                        }
                    }
                    if(a[t]) break;
                }
                if(!a[t]) break;
                for(int u = t; u != s; u = edges[p[u]].from){
                    edges[p[u]].flow += a[t];
                    edges[p[u]^1].flow -= a[t];
                }
                flow += a[t];
            }
            return flow;
        }
    
        void getMatrix()
        {
            int r = 0, c = 0;
            for(int i = 2*(n+m); i < edges.size(); i+=2){
                if(c==m) {
                    r++, c = 0;
                }
                ans[r][c] = edges[i].flow;
                c++;
            }
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    if(j==m-1) printf("%d
    ",ans[i][j]+1);
                    else printf("%d ",ans[i][j]+1);
                }
            }
        }
    };
    
    int main()
    {
        int n, m, T;
        scanf("%d",&T);
        for(int cas = 1; cas <= T; cas++){
            scanf("%d%d",&n,&m);
            for(int i = 0; i < n; i++) scanf("%d",&r[i]);
            for(int i = 0; i < m; i++) scanf("%d",&c[i]);
            for(int i = n-1; i > 0; i--) r[i] = r[i]-r[i-1];
            for(int i = m-1; i > 0; i--) c[i] = c[i]-c[i-1];
            int s, t;
            s = 0, t = n+m+1;
            EdmondsKarp ek;
            ek.init(t);
            ///s -> r
            for(int i = 0; i < n; i++) ek.AddEdge(s,i+1,r[i]-m);
            ///c -> t
            for(int i = 0; i < m; i++) ek.AddEdge(n+i+1,t,c[i]-n);
            ///r -> c
            for(int i = 0; i < n; i++){
                for(int j = 0; j < m; j++){
                    ek.AddEdge(i+1,n+j+1,19);
                }
            }
            int flow = ek.Maxflow(s,t);
            printf("Matrix %d
    ",cas);
            ek.n = n, ek.m = m;
            ek.getMatrix();
        }
        return 0;
    }
  • 相关阅读:
    __getitem__ 方法的使用
    python加载测试用例时,修改用例不必须以“test”开头
    python 反射
    python 类中__getattr__的使用
    python 中 __dict__函数的使用
    python 类中__int__和__str__的使用
    ubuntu16.04Nvidia驱动、CUDA、cuDNN安装与卸载
    C++中的各种可调用对象
    ubuntu16.04安装QGIS工具
    C/C++中extern关键字详解
  • 原文地址:https://www.cnblogs.com/xiaochaoqun/p/7190016.html
Copyright © 2011-2022 走看看