• 网络流24题之 1738: 最小路径覆盖问题


    网络流24题之 1738: 最小路径覆盖问题

    最小路径覆盖问题

    模板题,求一个图的最小路径覆盖,输出边数和,路径。不会输出路径的跑dinic然后把图输出来就懂了。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    int k;
    
    struct Dinic {
    
        static const int MAXN = 30005 + 7;
        static const int MAXM = 1e7 + 7;
        static const int INF = 0x3f3f3f3f;
    
        int n, m, s, t;
    
        int first[MAXN], cur[MAXN], dist[MAXN], sign;
    
        struct Node {
            int to, flow, next;
        } edge[MAXM];
    
        inline void init(int start, int vertex, int ss, int tt) {
            n = vertex, s = ss, t = tt;
            for(int i = start; i <= n; i++ ) {
                first[i] = -1;
            }
            sign = 0;
        }
    
        inline void addEdge(int u, int v, int flow) {
            edge[sign].to = v, edge[sign].flow = flow, edge[sign].next = first[u];
            first[u] = sign++;
        }
    
        inline void add_edge(int u, int v, int flow) {
            addEdge(u, v, flow);
            addEdge(v, u, 0);
        }
    
        int match[MAXN] = {0}, vis[MAXN] = {0};
    
        void show_graph() {
            int cnt = 0;
            for(int i = 1; i <= k; i++ ) {
                for(int j = first[i]; ~j; j = edge[j].next) {
                    int to = edge[j].to, w = edge[j].flow;
                    if(to != s && edge[j ^ 1].flow) {
                        match[i] = to - k;
                    }
                }
            }
            for(int i = 1; i <= k; i++ ) {
                int now = i;
                if(vis[i]) {
                    continue;
                }
                while(1) {
                    printf("%d", now);
                    vis[now] = 1;
                    now = match[now];
                    if(now == 0) {
                        cnt++;
                        puts("");
                        break;
                    } else {
                        printf(" ");
                    }
                }
            }
            printf("%d
    ", cnt);
        }
    
        inline int dinic() {
            int max_flow = 0;
            while(bfs(s, t)) {
                for(int i = 0; i <= n; i++ ) {
                    cur[i] = first[i];
                }
                max_flow += dfs(s, INF);
            }
            return max_flow;
        }
    
        bool bfs(int s, int t) {
            memset(dist, -1, sizeof(dist));
            queue<int>que;
            que.push(s), dist[s] = 0;
            while(!que.empty()) {
                int now = que.front();
                que.pop();
                if(now == t) {
                    return 1;
                }
                for(int i = first[now]; ~i; i = edge[i].next) {
                    int to = edge[i].to, flow = edge[i].flow;
                    if(dist[to] == -1 && flow > 0) {
                        dist[to] = dist[now] + 1;
                        que.push(to);
                    }
                }
            }
            return 0;
        }
    
        int dfs(int now, int max_flow) {
            if(now == t) {
                return max_flow;
            }
            int ans = 0, next_flow = 0;
            for(int &i = cur[now]; ~i; i = edge[i].next) {
                int to = edge[i].to, flow = edge[i].flow;
                if(dist[to] == dist[now] + 1 && flow > 0) {
                    next_flow = dfs(to, min(max_flow - ans, flow));
                    ans += next_flow;
                    edge[i].flow -= next_flow;
                    edge[i ^ 1].flow += next_flow;
                    if(ans == max_flow) {
                        return max_flow;
                    }
    
                }
            }
            if(ans == 0) {
                return dist[now] = 0;
            }
            return ans;
        }
    
    } cwl;
    
    int main() {
        int n, m;
        while(~scanf("%d %d", &n, &m)) {
            cwl.init(0, 2 * n + 1, 0, 2 * n + 1);
            for(int i = 1; i <= n; i++ ) {
                cwl.add_edge(0, i, 1);
                cwl.add_edge(i + n, 2 * n + 1, 1);
            }
            for(int i = 1; i <= m; i++ ) {
                int u, v;
                scanf("%d %d", &u, &v);
                cwl.add_edge(u, v + n, 1);
            }
            cwl.dinic();
            k = n;
            cwl.show_graph();
        }
        return 0;
    }
    
    
  • 相关阅读:
    程序员代码面试指南:IT名企算法与数据结构题目最优解
    经典排序算法
    Log4j输出格式控制--log4j的PatternLayout参数含义
    常用数据库4 mongodb
    常用数据库2 sqlite及SQL注入
    面试常问-数据库索引实现原理
    自定义web框架
    HTML|CSS之布局相关总结
    C++模板类练习题
    C++中的运算符重载练习题
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/9403632.html
Copyright © 2020-2023  润新知