zoukankan      html  css  js  c++  java
  • UVA

    很经典的网络流模型,行编号和列编号分别看成一个点,行和列和分别看出容量,一个点(x,y)看出是一条边,边的容量下界是1,所以先减去1,之后在加上就好了。

    建图的时候注意分配好编号,解从残留网络中的边找。

    前向星建图的话,打印解会比较麻烦。

    #include<bits/stdc++.h>
    using namespace std;
    
    const int maxn = 42;
    
    struct Edge
    {
        int v,cap,flow;
    };
    
    vector<Edge> edges;
    #define PB push_back
    
    vector<int> G[maxn];
    
    void AddEdge(int u,int v,int c)
    {
        G[u].PB(edges.size());
        edges.PB(Edge{v,c,0});
        G[v].PB(edges.size());
        edges.PB(Edge{u,0,0});
    }
    
    const int INF = 0x3f3f3f3f;
    int S,T;
    int vcnt;
    bool vis[maxn];
    int d[maxn];
    int q[maxn<<1];
    
    bool bfs()
    {
        memset(vis,0,sizeof(bool)*vcnt);
        int l = 0,r = 0;
        q[r++] = S; vis[S] = true;
        while(r>l){
            int u = q[l++];
            for(int i = 0; i < G[u].size(); i++){
                Edge &e = edges[G[u][i]];
                if(!vis[e.v] && e.cap >e.flow){
                    vis[e.v] = true;
                    d[e.v] = d[u]+1;
                    q[r++] = e.v;
                }
            }
        }
        return vis[T];
    }
    
    int cur[maxn];
    int dfs(int u,int a)
    {
        if(u == T||!a) return a;
        int flow = 0, f;
        for(int &i = cur[u]; i < G[u].size(); i++){
            Edge &e = edges[G[u][i]];
            if(d[e.v] == d[u]+1 && (f = dfs(e.v,min(a,e.cap-e.flow)))>0){
                e.flow += f;
                edges[G[u][i]^1].flow -= f;
                flow += f;
                a -= f;
                if(!a) break;
            }
        }
        return flow;
    }
    
    int MaxFlow()
    {
        int flow = 0;
        while(bfs()){
            memset(cur,0,sizeof(int)*vcnt);
            flow += dfs(S,INF);
        }
        return flow;
    }
    
    const int N = 20;
    int rid[N],cid[N];
    
    
    void init()
    {
        vcnt = 2;
        edges.clear();
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        S = 0; T = 1;
        int testCase; scanf("%d",&testCase);
        int mcnt = 0;
        while(testCase--){
            init();
            int R,C,cap,pre; scanf("%d%d",&R,&C);
    
            for(int i = 0, M = R+C+2; i < M; i++) G[i].clear();
            pre = 0;
            for(int i = 0; i < R; i++) {
                rid[i] = vcnt++;
                scanf("%d",&cap);
                AddEdge(S,rid[i],cap-pre-C);
                pre = cap;
            }
            pre = 0;
            for(int i = 0; i < C; i++){
                cid[i] = vcnt++;
                scanf("%d",&cap);
                AddEdge(cid[i],T,cap-pre-R);
                pre = cap;
            }
    
            for(int i = 0; i < R; i++)
            for(int j = 0; j < C; j++){
                AddEdge(rid[i],cid[j],19);
            }
    
            MaxFlow();
    
            printf("Matrix %d
    ",++mcnt);
            for(int i = 0; i < R; i++){
                int k = 0, u = rid[i];
                for(int j = 0; j < G[u].size(); j++){
                    Edge &e = edges[G[u][j]];
                    if(e.v == cid[k]){
                        printf("%d%c",e.flow+1,++k==C?'
    ':' ');
                        if(k == C) break;
                    }
                }
            }
    
            if(testCase) putchar('
    ');
        }
        return 0;
    }
  • 相关阅读:
    中专毕业后我的七年(励志篇,年轻人必看)
    Excel实战技巧之[二级条件级联]
    kingston DataTraveler2.0 4GU盘量产成功
    Windows XP SP3增强补丁 V1.3 破解uxtheme.dll和TCP/IP连接数的破解
    诺基亚系列手机型号命名研究
    硬件检测相关工具大全
    最好的MacOSX美化包——MacXize(支持SP3)
    我终于把《新概念英语》三册&四册全背下来了
    IBM T22故障
    Windows通用克隆系统入门基础知识简介
  • 原文地址:https://www.cnblogs.com/jerryRey/p/4759939.html
Copyright © 2011-2022 走看看