zoukankan      html  css  js  c++  java
  • POJ 1459最大流算法

    cin竟然比scanf慢了十几倍,想不通

    #include <iostream>
    #include <string>
    #include <vector>
    #include <cstdlib>
    #include <cmath>
    #include <map>
    #include <algorithm>
    #include <list>
    #include <ctime>
    #include <set>
    #include <queue>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    #define INT_MAX 10000000
    #define N 105
    #define CLR(arr, what) memset(arr, what, sizeof(arr))
    int capacity[N][N]; //容量
    int flow[N]; //残余流量
    int pre[N]; //前趋
    int n; //节点个数
    
    queue<int> Q;
    
    int BFS(int src, int des) {
        //初始化
        while (!Q.empty()) {
            Q.pop();
        }
        for (int i = 1; i < n + 1; i++) {
            pre[i] = -1;
        }
        pre[src] = 0;
        flow[src] = INT_MAX; //初始化源点的流量为无穷大
        Q.push(src);
        while (!Q.empty()) {
            int index = Q.front();
            Q.pop();
            if (index == des) { //找到了增广路径
                break;
            }
            for (int i = 1; i < n + 1; i++) {
                if (i != src && capacity[index][i] > 0 && pre[i] == -1) {
                    pre[i] = index;
                    //增广路残容流量
                    flow[i] = min(capacity[index][i], flow[index]);
                    Q.push(i);
                }
            }
        } //while
        if (pre[des] == -1) {
            return -1; //残留图中不存在增广路径
        } else {
            return flow[des];
        }
    }
    
    int MaxFlow(int src, int des) {
        int aug = 0;
        int sumflow = 0;
        while ((aug = BFS(src, des)) != -1) {
            int k = des; //利用前驱寻找路径
            while (k != src) {
                int last = pre[k];
                capacity[last][k] -= aug;
                capacity[k][last] += aug;
                k = last;
            }
            sumflow += aug;
        }
        return sumflow;
    }
    struct node {
        string in, out;
        int cap;
    };
    int checkin(string & a, string& b) {
        int sz = a.size();
        bool judge = 1;
        for (int i = 0; i < sz; i++) {
            if (a[i] == '2' || b[i] == '2') {
                continue;
            } else if (a[i] != b[i]) {
                judge = 0;
                break;
            }
        }
        if (1 == judge)
            return 1;
        return 0;
    }
    
    int cur[N]; //后继
    int dis[N]; //距离
    int gap[N]; //层结点数(用于间隙优化)
    int SAP(int s, int t) //源点、汇点、结点数
            {
        CLR(gap, 0);
        CLR(cur, 0);
        CLR(dis, 0);
        int u = pre[s] = s, maxflow = 0, aug = INT_MAX;
        int v;
        gap[0] = n;
        while (dis[s] < n) {
            bool flag = false;
            for (v = cur[u]; v <= n; ++v) //寻找允许弧
                    {
                if (capacity[u][v] > 0 && dis[u] == dis[v] + 1) {
                    flag = true;
                    break;
                }
            }
            if (flag) //找到允许弧
            {
                pre[v] = u;
                cur[u] = v;
                aug = min(aug, capacity[u][v]);
                u = v;
                if (v == t) //找到完整增广路
                        {
                    maxflow += aug;
                    for (v = t; v != s; v = pre[v]) //更新残留网络
                            {
                        capacity[pre[v]][v] -= aug; //正向边
                        capacity[v][pre[v]] += aug; //反向边
                    }
                    aug = INT_MAX;
                    u = s; //重新从源点寻找
                }
            } else //找不到允许弧
            {
                int mindis = n;
                for (v = 1; v <= n; ++v) //重新标号
                        {
                    if (capacity[u][v] && mindis > dis[v]) {
                        cur[u] = v;
                        mindis = dis[v];
                    }
                }
                if (--gap[dis[u]] == 0) //更新断层 + 判断是否断层(间隙优化)
                    break;
                gap[dis[u] = mindis + 1]++; //更新断层
                u = pre[u]; //当前弧优化
            }
        }
        return maxflow;
    }
    
    inline void addedge(int x, int y, int c) { // add an arc(x -> y, c); vertex: 0 ~ n-1;
        capacity[x][y] = c;
    }
    
    int main() {
        int t, np, nc, m, power, id, u, v, cap;
        char tmp;
        while (cin >> t) {
            scanf("%d%d%d", &np, &nc, &m);
            int curn = t + 2;
            n = curn;
            memset(capacity, 0, sizeof(capacity));
            for (int i = 0; i < m; i++) {
                scanf(" (%d,%d)%d ", &u, &v, &cap);
                if (u == v) {
                    continue;
                } else {
                    u++;
                    v++;
                    addedge(u, v, cap);
                }
            }
            for (int i = 0; i < np; i++) {
                scanf(" (%d)%d ", &id, &power);
                addedge(0, id + 1, power);
            }
            for (int i = 0; i < nc; i++) {
                int power, id;
                scanf(" (%d)%d ", &id, &power);
                addedge(id + 1, curn - 1, power);
            }
            int sum = MaxFlow(0, curn - 1);
    //int sum = SAP( 0, curn - 1);
            cout << sum << endl;
        }
        return 0;
    }
  • 相关阅读:
    Iterator 迭代器
    Collection-List
    Collection-Set
    Collection
    多线程
    面向对象<高级>知识点
    链表
    面向对象<基础>知识点
    三层架构和MVC模式详解
    impala为什么比hive快
  • 原文地址:https://www.cnblogs.com/kakamilan/p/3055494.html
Copyright © 2011-2022 走看看