zoukankan      html  css  js  c++  java
  • 网络流解决混合欧拉回路问题

    网络流解决混合欧拉回路问题

    解析

    image.png

    例题

    欧拉回路,只不过图即存在有向边,又存在无向边,问是否存在欧拉回路

    n点, m边的图,下面m条边。标准图论输入

    下面代码中的路径第三个值为‘1’表示有向边,否则是双向边。

    代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    struct Dinic {
    
        static const int MAXN = 1050 + 7;
        static const int MAXM = MAXN * MAXN;
        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 * 4];
    
        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 add_edge(int u, int v, int flow) {
            edge[sign].to = v, edge[sign].flow = flow, edge[sign].next = first[u];
            first[u] = sign++;
            edge[sign].to = u, edge[sign].flow = 0, edge[sign].next = first[v];
            first[v] = sign++;
        }
    
        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;
        }
    
    } dinic;
    
    const int MAXN = 1050;
    
    int n, m;
    
    int indeg[MAXN], outdeg[MAXN];
    
    struct Input {
        int u, v, d;
    } edge[MAXN];
    
    int main()
    {
        while(~scanf("%d %d", &n, &m)) {
            memset(indeg, 0, sizeof(indeg));
            memset(outdeg, 0, sizeof(outdeg));
            dinic.init(0, n + 1, 0, n + 1);
            for(int i = 1; i <= m; i++ ) {
                scanf("%d %d %d", &edge[i].u, &edge[i].v, &edge[i].d);
                indeg[ edge[i].v ]++;
                outdeg[ edge[i].u ]++;
                if(edge[i].d == 0) {
                    dinic.add_edge(edge[i].u, edge[i].v, 1);
                    dinic.add_edge(edge[i].v, edge[i].u, 1);
                }
            }
            bool ok = 1;
            int sum = 0;
            for(int i = 1; i <= n; i++) {
                int delta = abs(indeg[i] - outdeg[i]);
                if(delta % 2 == 1) {
                    ok = 0;
                    break;
                }
                if(indeg[i] > outdeg[i]) {
                    dinic.add_edge(0, i, delta / 2);
                    sum += delta / 2;
                } else {
                    dinic.add_edge(i, n + 1, delta / 2);
                }
            }
            if(!ok) {
                puts("impossible");
                continue;
            }
            if(dinic.dinic() == sum) {
                puts("possible");
            } else {
                puts("impossible");
            }
        }
        return 0;
    }
    
    
  • 相关阅读:
    Mina之session
    进程管理
    Mina之polling
    用户和组ID
    Mina之service
    同步化、同步及异步操作
    高级进程管理
    一般文件I/O用法建议
    有一个图像搜索引擎
    图像处理和识别和机器学习源码
  • 原文地址:https://www.cnblogs.com/Q1143316492/p/9832459.html
Copyright © 2011-2022 走看看