zoukankan      html  css  js  c++  java
  • UVA

    2. B - Matrix Decompressing

    题意:定义一个R*C的正整数矩阵(1<=R,C<=20),设Ai为前i行所有元素之和,Bi为前i列所有元素之和。
    题目已知R,C和数组A,B。要找一个满足条件的矩阵。矩阵中的元素要满足(1<=X[i][j]<=20)。


    思路:

    此处输入图片的描述

    根据a,b数组求出每一行的元素之和a,每一列的元素之和b 建一个源点s=0,汇点t=R+C+1
    然后每一行看成一个顶点1~R,每一列看成一个顶点R+1~R+C
    矩阵中每一个位置看成是一条边,比如2行3列的点,就是连接第2行和第3列的点的边。 然后从s到每一行建一条边,容量为a[i],
    从每一列到t建一条边,容量为b[i] 然后每一行的点向每一列的点建边,容量为20(暂且说是20,继续看下去,20是错的,19才是对的)
    这样的图的意义: 整个矩阵的和代表总的流量 从s出发,分别流向R行(所以有a1+…+a[R]=总流量)
    每一行的流量会分给该行的C个元素,每一个列的顶点会从R行获得总的流量,就是该列的流量,最后流到t的总流量还是s出发的流量。
    所以行的顶点和列的顶点的R*C条边流过的流量就代表矩阵中R*C个位置的值。
    因为题目要求矩阵的位置的值在1~20之间,
    所以R*C条边的流量应该在1~20之间,所以R*C条边的最大流量即容量就是20.

    但是这样是有问题的,我们好像忽略了一个问题,如果某一条边没有流量怎么办?
    某一条边流量为0的情况下,就不能满足矩阵中的元素在1~20之间了
    可以先给所有的边给一个值为1的流量,这样的话条件就改成了1~19 了。
    求到的最后流量值+1就是矩阵中的元素值。

    解决代码:

    #include<bits/stdc++.h>
    #define maxn 1000
    #define INF (1<<31)-1
    
    using namespace std;
    
    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 Dinic
    {
        int n,m,s,t;
        vector<Edge> edges;
        vector<int> G[maxn];
        int d[maxn];
        int cur[maxn];
        bool vis[maxn];
    
        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);
        }
    
        bool BFS()
        {
            memset(vis,false,sizeof(vis));
            for (int i=0; i<n; i++) d[i] = INF;
            d[s] = 0; vis[s] = true;
    
            queue<int> Q;
            Q.push(s);
            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 (!vis[e.to] && e.cap>e.flow)
                    {
                        vis[e.to] = true;
                        d[e.to] = d[x]+1;
                        Q.push(e.to);
                    }
                }
            }
            return vis[t];
        }
    
        int DFS(int x,int a)
        {
            if (x == t || a == 0)
                return a;
            int flow = 0,f;
            for (int i=cur[x]; i<G[x].size(); i++)
            {
                Edge& e = edges[G[x][i]];
                if (d[e.to] == d[x]+1 && (f = DFS(e.to,min(a,e.cap-e.flow))) > 0)
                {
                    e. flow += f;
                    edges[G[x][i]^1].flow -= f;
                    flow += f;
                    a -= f;
                    if (a == 0)
                        break;
                }
            }
            return flow;
        }
    
        bool OKA()
        {
            for (int i=0; i<G[s].size(); i++)
            {
                Edge e = edges[G[s][i]];
                if (e.cap!=e.flow)
                    return false;
            }
            return true;
        }
    
        bool OKB(int R,int C)
        {
            for (int j=R+1; j<=R+C; j++)
            {
                Edge& e = edges[G[j][0]];
                if (e.cap!=e.flow)
                    return false;
            }
            return true;
        }
    
        void Maxflow(int t,int R,int C)
        {
            int flow = 0;
            while (BFS())
            {
                memset(cur,0,sizeof(cur));
                flow += DFS(s,INF);
            }
    
            cout<<"Matrix "<<t<<endl;
            if (OKA() && OKB(R,C))
            {
                for (int i=1; i<=R; i++)
                {
                    int j;
                    for (j=1; j<G[i].size()-1; j++)
                        cout<<edges[G[i][j]].flow+1<<' ';
                    cout<<edges[G[i][j]].flow+1<<endl;
                }
            }
            cout<<endl;
        }
    };
    
    int main()
    {
        Dinic aa;
        int T,R,C,tmp;
        int a[30],b[30],c[30],d[30];
     #ifndef ONLINE_JUDGE
        freopen("1.in", "r", stdin);
        freopen("1.out", "w", stdout);
    #endif
        cin>>T;
        tmp = T;
        while (T>0)
        {
            T--;
            aa.init(maxn);
            cin>>R>>C;
            for (int i=1; i<=R; i++) cin>>a[i];
            for (int i=1; i<=C; i++) cin>>b[i];
            for (int i=1; i<=R; i++) c[i] = a[i]-a[i-1]-C;
            for (int i=1; i<=C; i++) d[i] = b[i]-b[i-1]-R;
    
            for (int i=1; i<=R; i++)
                aa.Addedge(0,i,c[i]);
            for (int i=1; i<=C; i++)
                aa.Addedge(R+i,R+C+1,d[i]);
            for (int i=1; i<=R; i++)
                for (int j=1; j<=C; j++)
                    aa.Addedge(i,R+j,19);
            aa.s = 0; aa.t = R+C+1;
            aa.Maxflow(tmp-T,R,C);
        }
        return 0;
    }
    
  • 相关阅读:
    登录页面上的验证码的生成
    数据库操作中使用事务进行提速
    Dotnet程序集自动生成版本号
    .NET与Java的Web Services相互调用(转)
    Struts配置
    C# WebService发布与调用方法(转)
    WinCE中C#WinForm利用Web Service查询数据库(转)
    C#打包
    VS2008快捷键大全
    这些话你懂吗?
  • 原文地址:https://www.cnblogs.com/bryce1010/p/9386888.html
Copyright © 2011-2022 走看看