zoukankan      html  css  js  c++  java
  • uva11082 Matrix Decompressing

    网络流

    首先算出每行每列的数的和。

    每行的值减去c,每列的值减去R

    然后每行和每列之间连边,容量为19.

    这样一来,(i,j)的流量相当于(i,j)的值-1.

    这样就避免了流量为0不对应答案的尴尬情况。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 1000 + 10;
    const int maxm = 100000 + 10;
    const int inf = 0x3f3f3f3f;
    
    int g[maxn],v[maxm],nex[maxm],f[maxm],eid;
    int gap[maxn],d[maxn],vid;
    int n,m,S,T;
    int a[maxn],b[maxn];
    int res[maxn][maxn];
    
    void addedge(int a,int b,int F) {
        v[eid]=b; f[eid]=F; nex[eid]=g[a]; g[a]=eid++;
        v[eid]=a; f[eid]=0; nex[eid]=g[b]; g[b]=eid++;         
    }
    
    void build() {
        memset(a,0,sizeof(a));
        memset(b,0,sizeof(b));
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) scanf("%d",&a[i]);
        for(int i=n;i>=1;i--) a[i]-=a[i-1];
        for(int i=n+1;i<=n+m;i++) scanf("%d",&b[i]);
        for(int i=n+m;i>=n+1;i--) b[i]-=b[i-1];
        memset(g,-1,sizeof(g)); eid=0;
        S=n+m+1; T=n+m+2; vid=n+m+2;
        for(int i=1;i<=n;i++) {
            addedge(S,i,a[i]-m);
        }
        for(int i=n+1;i<=n+m;i++) {
            addedge(i,T,b[i]-n);
        }
        for(int i=1;i<=n;i++) 
        for(int j=n+1;j<=n+m;j++) {
            addedge(i,j,19);
        }
    }
    
    int ISAP(int u,int flow) {
        if(u==T) return flow;
        int cur=0,aug,mindist=vid;
        
        for(int i=g[u];~i;i=nex[i]) if(f[i] && d[u]==d[v[i]]+1) {
            aug=ISAP(v[i],min(flow-cur,f[i]));
            cur+=aug;
            f[i]-=aug;
            f[i^1]+=aug;
            if(cur==flow || d[S]>=vid) return cur;
        }
        
        if(cur==0) {
            if(!--gap[d[u]]) {
                d[S]=vid;
                return cur;
            }
            for(int i=g[u];~i;i=nex[i]) if(f[i]) 
                mindist=min(mindist,d[v[i]]);
            ++gap[d[u]=mindist+1];
        }
        return cur;
    }
    
    void solve() {
        memset(d,0,sizeof(d));
        memset(gap,0,sizeof(gap));
        gap[0]=vid;
        while(d[S]<vid) {
    
            ISAP(S,inf);
        }
        for(int u=1;u<=n;u++) {
            for(int i=g[u];~i;i=nex[i]) res[u][v[i]]=20-f[i];
        }
        for(int i=1;i<=n;i++) {
            for(int j=n+1;j<n+m;j++) 
                printf("%d ",res[i][j]);
            printf("%d
    ",res[i][n+m]);
        }
    }
    
    int main() {
        int T;
        scanf("%d",&T);
        for(int i=1;i<=T;i++) {
            if(i>1) printf("
    ");
            printf("Matrix %d
    ",i);
            build();
            solve();
        }
        return 0;
    }
  • 相关阅读:
    洛谷#P5652#基础博弈练习题
    hgoi#20191112
    hgoi#20191111
    hgoi#20191109
    洛谷#P3674#小清新人渣的本愿
    hgoi#20191108
    hgoi#20191107
    树上差分
    树链剖分(树剖)
    LCA(最近公共祖先)问题
  • 原文地址:https://www.cnblogs.com/invoid/p/5569068.html
Copyright © 2011-2022 走看看