hdu 4975 最大流快版

来源:互联网 发布:傲剑丹田升级数据一游 编辑:程序博客网 时间:2024/04/30 21:57

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\n", 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();    }}


0 0
原创粉丝点击