zoukankan      html  css  js  c++  java
  • UVA

    题目大意:给出一个R行C列的矩阵,如今给出他的前1-R行和 && 前1-C列和,问这个矩阵原来是如何的,要求每一个元素大小在1-20之间

    解题思路:将每一行连接到超级源点,容量为该行的和-列数
    将每一列连接到超级汇点,容量为该列的和-行数
    接着将每行连接到该行的每一个元素,容量为19
    将每一个元素连接到元素所在列。容量为19
    为什么容量为19,由于跑最大流的时候有可能边的流量为0,而他要求的是每一个数的范围在1-20之间,所以最后的答案都要加上1。这也解释了为什么连接到超级源点和超级汇点的容量要减去对应的值

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <vector>
    #include <queue>
    using namespace std;
    #define N 1010
    #define INF 0x3f3f3f3f
    
    struct Edge{
        int from, to, cap, flow;
        Edge() {}
        Edge(int from, int to, int cap, int flow) : from(from), to(to), cap(cap), flow(flow) {}
    };
    
    struct Dinic{
        int n, m, s, t;
        vector<Edge> edges;
        vector<int> G[N];
        bool vis[N];
        int d[N], cur[N];
    
        void init(int n) {
            this->n = 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));
            int m = edges.size();
            G[from].push_back(m - 2);
            G[to].push_back(m - 1);
        } 
    
        bool BFS() {
            memset(vis, 0, sizeof(vis));
            queue<int> Q;
            Q.push(s);
            vis[s] = 1;
            d[s] = 0;
    
            while (!Q.empty()) {
                int u = Q.front();
                Q.pop();
                for (int i = 0; i < G[u].size(); i++) {
                    Edge &e = edges[G[u][i]];
                    if (!vis[e.to] && e.cap > e.flow) {
                        vis[e.to] = true;
                        d[e.to] = d[u] + 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[x] + 1 == d[e.to] && (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;
        }
    
        int Maxflow(int s, int t) {
            this->s = s; this->t = t;
            int flow = 0;
            while (BFS()) {
                memset(cur, 0, sizeof(cur));
                flow += DFS(s, INF);
            }
            return flow;
        }
    };
    
    Dinic dinic;
    
    int n, m, cas = 1;
    int SumRow[N], SumCol[N], row[N], col[N];
    void init() {
        scanf("%d%d", &n, &m);
        for (int i = 1; i <= n; i++) 
            scanf("%d", &SumRow[i]);
        for (int i = 1; i <= m; i++)
            scanf("%d", &SumCol[i]);
    
        int source = 0, sink = n * m + n + m + 1;
        dinic.init(sink);
    
    
        row[1] = SumRow[1];
        dinic.AddEdge(source, n * m + 1, row[1] - m);
        for (int i = 2; i <= n; i++) {
            row[i] = SumRow[i] - SumRow[i - 1];
            dinic.AddEdge(source, n * m + i, row[i] - m);
        }
    
        col[1] = SumCol[1];
        dinic.AddEdge(n * m + n + 1, sink, SumCol[1] - n);
        for (int i = 2; i <= m; i++) {
            col[i] = SumCol[i] - SumCol[i - 1];
            dinic.AddEdge(n * m + n + i, sink, col[i] - n);
        }
    
        for (int i = 0; i < n; i++)
            for (int j = 1; j <= m; j++) {
                dinic.AddEdge(n * m + i + 1, i * m + j, 19);
                dinic.AddEdge(i * m + j, n * m + n + j, 19);
            }
        int ans = dinic.Maxflow(source, sink);
        printf("Matrix %d
    ", cas++);
        for (int i = 0; i < n; i++) {
            for (int j = 1; j <= m; j++) {
                if (j != 1)
                    printf(" ");
                for (int k = 0; k < dinic.G[i*m+j].size(); k++) {
                    int u = dinic.edges[dinic.G[i*m+j][k]].from;
                    int v = dinic.edges[dinic.G[i*m+j][k]].to;
    
                    if (u == i * m + j && v == n * m + n + j) {
                        printf("%d", dinic.edges[dinic.G[i*m+j][k]].flow + 1);
                        break;
                    }
                }
            }
            printf("
    ");
        }
    }
    
    int main() {
        int test;
        scanf("%d", &test);
        while (test--) {
            init();
            if (test)
                printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    记录下QCustomPlot 热力图的用法
    Qt QChart 创建图表
    Qt TCP 简单通信
    Qt 设置Qt::FramelessWindowHint 后界面无法移动问题的一种解决方案
    Qt 操作 Excel 的相关文档
    Microsoft Word Application Reference Qt 操作word 的操作文档
    Python 进行excel查重
    Qt QPainter画个球啊
    Redis持久性文档中文翻译
    Docker 课前预习
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7248545.html
Copyright © 2011-2022 走看看