zoukankan      html  css  js  c++  java
  • hdu 4975 最大流快版

    http://acm.hdu.edu.cn/showproblem.php?pid=4975

    给出每行每列的和,问是否存在这样的表格;每个小格放的数字只能是0--9。


    直接用第八场最大流模板.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #include <numeric>
    using namespace std;
    typedef long long LL;
    
    const int MAXN = 610;
    const int MAXV = MAXN << 1;
    const int MAXE = 2 * MAXN * MAXN;
    const int INF = 0x3f3f3f3f;
    
    struct ISAP {
        int head[MAXV], cur[MAXV], gap[MAXV], dis[MAXV], pre[MAXV];
        int to[MAXE], next[MAXE], flow[MAXE];
        int n, ecnt, st, ed;
    
        void init(int n) {
            this->n = n;
            memset(head + 1, -1, n * sizeof(int));
            ecnt = 0;
        }
    
        void add_edge(int u, int v, int c) {
            to[ecnt] = v; flow[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
            to[ecnt] = u; flow[ecnt] = 0; next[ecnt] = head[v]; head[v] = ecnt++;
        }
    
        void bfs() {
            memset(dis + 1, 0x3f, n * sizeof(int));
            queue<int> que; que.push(ed);
            dis[ed] = 0;
            while(!que.empty()) {
                int u = que.front(); que.pop();
                gap[dis[u]]++;
                for(int p = head[u]; ~p; p = next[p]) {
                    int v = to[p];
                    if(flow[p ^ 1] && dis[u] + 1 < dis[v]) {
                        dis[v] = dis[u] + 1;
                        que.push(v);
                    }
                }
            }
        }
    
        int max_flow(int ss, int tt) {
            st = ss, ed = tt;
            int ans = 0, minFlow = INF;
            for(int i = 0; i <= n; ++i) {
                cur[i] = head[i];
                gap[i] = 0;
            }
            bfs();
            int u = pre[st] = st;
            while(dis[st] < n) {
                bool flag = false;
                for(int &p = cur[u]; ~p; p = next[p]) {
                    int v = to[p];
                    if(flow[p] && dis[u] == dis[v] + 1) {
                        flag = true;
                        minFlow = min(minFlow, flow[p]);
                        pre[v] = u;
                        u = v;
                        if(u == ed) {
                            ans += minFlow;
                            while(u != st) {
                                u = pre[u];
                                flow[cur[u]] -= minFlow;
                                flow[cur[u] ^ 1] += minFlow;
                            }
                            minFlow = INF;
                        }
                        break;
                    }
                }
                if(flag) continue;
                int minDis = n - 1;
                for(int p = head[u]; ~p; p = next[p]) {
                    int &v = to[p];
                    if(flow[p] && dis[v] < minDis) {
                        minDis = dis[v];
                        cur[u] = p;
                    }
                }
                if(--gap[dis[u]] == 0) break;
                ++gap[dis[u] = minDis + 1];
                u = pre[u];
            }
            return ans;
        }
    
        int stk[MAXV], top;
        bool sccno[MAXV], vis[MAXV];
    
        bool dfs(int u, int f, bool flag) {
            vis[u] = true;
            stk[top++] = u;
            for(int p = head[u]; ~p; p = next[p]) if(flow[p]) {
                int v = to[p];
                if(v == f) continue;
                if(!vis[v]) {
                    if(dfs(v, u, flow[p ^ 1])) return true;
                } else if(!sccno[v]) return true;
            }
            if(!flag) {
                while(true) {
                    int x = stk[--top];
                    sccno[x] = true;
                    if(x == u) break;
                }
            }
            return false;
        }
    
        bool acycle() {
            memset(sccno + 1, 0, n * sizeof(bool));
            memset(vis + 1, 0, n * sizeof(bool));
            top = 0;
            return dfs(ed, 0, 0);
        }
    } G;
    
    int row[MAXN], col[MAXN];
    int mat[MAXN][MAXN];
    int n, m, k, ss, tt;
    
    void solve() {
        int sumr = accumulate(row + 1, row + n + 1, 0);
        int sumc = accumulate(col + 1, col + m + 1, 0);
        if(sumr != sumc) {
            puts("So naive!");
            return ;
        }
        int res = G.max_flow(ss, tt);
        if(res != sumc) {
            puts("So naive!");
            return ;
        }
        if(G.acycle()) {
            puts("So young!");
        } else {
            puts("So simple!");
    //        for(int i = 1; i <= n; ++i) {
    //            for(int j = 1; j < m; ++j) printf("%d ", G.flow[mat[i][j]]);
    //            printf("%d
    ", G.flow[mat[i][m]]);
    //        }
        }
    }
    
    int main() {
        int _;
        scanf("%d",&_);
        for(int cas = 1;cas <= _;++cas)
        {
            printf("Case #%d: ",cas);
            scanf("%d%d", &n, &m );
            k = 9;
            for(int i = 1; i <= n; ++i) scanf("%d", &row[i]);
            for(int i = 1; i <= m; ++i) scanf("%d", &col[i]);
            ss = n + m + 1, tt = n + m + 2;
            G.init(tt);
            for(int i = 1; i <= n; ++i) G.add_edge(ss, i, row[i]);
            for(int i = 1; i <= m; ++i) G.add_edge(n + i, tt, col[i]);
            for(int i = 1; i <= n; ++i) {
                for(int j = 1; j <= m; ++j) {
                    mat[i][j] = G.ecnt ^ 1;
                    G.add_edge(i, n + j, k);
                }
            }
            solve();
        }
    }


  • 相关阅读:
    如何将SQLServer2005中的数据同步到Oracle中【转】
    八大排序算法总结[转]
    Web报表相关汇集(个人收藏)
    分析:城域网技术PBT交锋TMPLS
    Ubuntu下通过SSH远程登录服务器的方法
    关于VC代码的编写和调试(三)
    Start Starts a separate window to run a specified program or command.
    罗技劲雕鼠标移动速度过慢问题
    Microsoft XML Core Services 4.0 SP2 KB936181老是提示安装(转,不过我也遇到这个问题了)
    四川人逆境中的幽默
  • 原文地址:https://www.cnblogs.com/zibaohun/p/4046804.html
Copyright © 2011-2022 走看看