• UVA-11082 Matrix Decompressing (网络流建模)


    题目大意:给出一个由1到20组成的整数矩阵的每一行和每一列的和,构造这个矩阵。输出任意一个构造方案。

    题目分析:将每一行视作一个点x,将每一列视作一个点y。对于矩阵中的每一个格子,都对应一个二元关系<x,y>,从x连一条有向弧到y,容量置为19。增加源点s和汇点t,对于每一个x,连一条从s到x的有向弧,容量置为对应的该行总和减去列数,对于每一个y,连一条从y到t的有向弧,容量置为对应的该列总和减去行数。对于这个寻找最大流,算法终止后,如果从s出发的每一条弧和到达t的每一条弧都是饱和的,那么每一个xi到yj的流量便是对应格子中的值减一;否则,无解。这道题,一定有解。  显然,这样建模是正确的。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<string>
    # include<vector>
    # include<list>
    # include<set>
    # include<map>
    # include<queue>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    # define LL long long
    # define REP(i,s,n) for(int i=s;i<n;++i)
    # define CL(a,b) memset(a,b,sizeof(a))
    # define CLL(a,b,n) fill(a,a+n,b)
    
    const double inf=1e30;
    const int INF=1<<30;
    const int N=1000;
    
    struct Edge
    {
        int fr,to,cap,flow;
        Edge(int _fr,int _to,int _cap,int _flow):fr(_fr),to(_to),cap(_cap),flow(_flow){}
    };
    vector<Edge>edge;
    int id[50][50],r,c,a[25],b[25],f[50],p[50];
    vector<int>G[50];
    
    void init()
    {
        a[0]=b[0]=0;
        REP(i,0,r+c+2) G[i].clear();
        edge.clear();
    }
    
    void addEdge(int fr,int to,int cap)
    {
        edge.push_back(Edge(fr,to,cap,0));
        edge.push_back(Edge(to,fr,0,0));
        int m=edge.size();
        id[fr][to]=m-2;
        G[fr].push_back(m-2);
        G[to].push_back(m-1);
    }
    
    void maxFlow(int s,int t)
    {
        while(1)
        {
            queue<int>q;
            CL(f,0);
            f[s]=INF;
            q.push(s);
            while(!q.empty()){
                int u=q.front();
                q.pop();
                REP(i,0,G[u].size()){
                    Edge &e=edge[G[u][i]];
                    if(!f[e.to]&&e.cap>e.flow){
                        p[e.to]=G[u][i];
                        f[e.to]=min(f[u],e.cap-e.flow);
                        q.push(e.to);
                    }
                }
                if(f[t]) break;
            }
            if(!f[t]) break;
            for(int u=t;u!=s;u=edge[p[u]].fr){
                edge[p[u]].flow+=f[t];
                edge[p[u]^1].flow-=f[t];
            }
        }
    }
    
    int main()
    {
        int T,cas=0;
        scanf("%d",&T);
        while(T--)
        {
            scanf("%d%d",&r,&c);
            init();
            REP(i,1,r+1) scanf("%d",a+i);
            REP(i,1,c+1) scanf("%d",b+i);
            REP(i,1,r+1) addEdge(0,i,a[i]-a[i-1]-c);
            REP(i,1,r+1) REP(j,r+1,r+c+1) addEdge(i,j,19);
            REP(i,r+1,r+c+1) addEdge(i,r+c+1,b[i-r]-b[i-r-1]-r);
            maxFlow(0,r+c+1);
            printf("Matrix %d
    ",++cas);
            REP(i,1,r+1) REP(j,1,c+1) printf("%d%c",edge[id[i][j+r]].flow+1,(j==c)?'
    ':' ');
            if(T) printf("
    ");
        }
      return 0;
    }
    

      

  • 相关阅读:
    EditPlus使用技巧
    PL/SQL Dev的问题
    解决httpModules 未能从程序集 XX 加载类型 XXX 的错误
    IE浏览器无法显示背景,字体显示很大问题的解决办法[转]
    如何在Outlook2003中加入农历节气
    再谈Oracle在Windows下的权限问题
    Vista下安装布署注册的问题解决
    [转]关于管理的经典故事(员工激励)
    开始应用AJAX
    Aptana IDE 中文乱码的问题解决
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5011647.html
Copyright © 2020-2023  润新知