zoukankan      html  css  js  c++  java
  • bzoj2597

    费用流

    反过来做,考虑什么情况下不行

    对于三个点,当一个点出度为$2$时不形成三元环

    设$x$度数为$d_x$,那么不形成的三元环就是$frac{d_x(d_x-1)}{2}$

    建图,一边是点,一边是边,边向汇连容量为$1$费用为$0$的边

    点连向对应边

    原点向点连$n-1$条边,费用递增

    跑最小费用流,总数减去就是答案

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 1e4 + 5, inf = 0x3f3f3f3f;
    struct edge {
        int nxt, to, f, c;
    } e[maxn * 100];
    int n, m, k, source, sink, cnt = 1;
    int head[maxn], pree[maxn], Prev[maxn], vis[maxn], d[maxn];
    inline void link(int u, int v, int f, int c) {
        e[++cnt].nxt = head[u];
        head[u] = cnt;
        e[cnt].f = f;
        e[cnt].to = v;
        e[cnt].c = c;
    }
    inline void insert(int u, int v, int f, int c) {
        link(u, v, f, c);
        link(v, u, 0, -c);
    }
    bool spfa() {
        memset(d, -1, sizeof(d));
        d[source] = 0;
        queue<int> q;
        q.push(source);
        while(!q.empty()) {
            int u = q.front();
            q.pop();
            vis[u] = 0;
            for(int i = head[u]; i; i = e[i].nxt) {
                if(e[i].f && (d[e[i].to] > d[u] + e[i].c || d[e[i].to] == -1)) {
                    pree[e[i].to] = i;
                       Prev[e[i].to] = u;
                    d[e[i].to] = d[u] + e[i].c;
                    if(vis[e[i].to] == 0) {
                        q.push(e[i].to);
                        vis[e[i].to] = 1;
                    }
                }
            }
        }
        return ~d[sink]; 
    }
    inline int Edmonds_Karp() {
        int ans = 0;
        while(spfa()) {
            int now = sink, delta = inf;
            while(now != source) {
                delta = min(delta, e[pree[now]].f);
                now = Prev[now];
            }
            now = sink;
            while(now != source) {
                e[pree[now]].f -= delta;
                e[pree[now] ^ 1].f += delta; 
                now = Prev[now];
            }
            ans += delta * d[sink];
        } 
        return ans;
    }
    int a[105][105], id[105][105];
    int main() {
        scanf("%d", &n);
        source = maxn - 2;
        sink = maxn - 1;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                scanf("%d", &a[i][j]);
            }
        }
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n - 1; ++j) {
                insert(source, i, 1, j);
            }
        }
        int tot = n;
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < i; ++j) {
                insert(++tot, sink, 1, 0);
                if(a[i][j] == 0 || a[i][j] == 2) {
                    insert(i, tot, 1, 0);
                    id[j][i] = cnt - 1;
                }
                if(a[i][j] == 1 || a[i][j] == 2) {
                    insert(j, tot, 1, 0);
                    id[i][j] = cnt - 1;
                }
            }
        }
        int ans = n * (n - 1) * (n - 2) / 6;
        printf("%d
    ", ans - Edmonds_Karp());
        for(int i = 0; i < n; ++i) {
            for(int j = 0; j < n; ++j) {
                if(i == j) {
                    printf("0");
                } else {
                    printf("%d", !id[i][j] || e[id[i][j]].f ? 0 : 1);
                }
                printf("%c", j == n - 1 ? '
    ' : ' ');
            }
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Java EE (3) -- Java EE 6 Web Services Developer Certified Expert(1z0-897)
    二、用电信号传输 TCP/IP 数据(1)
    P2384 最短路 洛谷
    T1231 最优布线 codevs
    P3371 单源最短路径【模板】 洛谷
    spfa【模板】
    P1396 营救 洛谷
    解决Android加固多进程ptrace反调试的思路整理
    Android Dex文件格式解析
    360加固保so动态脱壳
  • 原文地址:https://www.cnblogs.com/19992147orz/p/11999852.html
Copyright © 2011-2022 走看看