• Dinic


    不说什么了,代码解释

    #include<bits/stdc++.h>
    #define repeat(a,b,c,g) for (int a=b,abck=(g>=0?1:-1);abck*(a)<=abck*(c);a+=g)
    using namespace std;
    struct edge{
        int v,flow,by;//v表示指向的边,flow表示最大流流量,by是它的反向边位置
    };
    vector <edge> f[100010];//用vector模拟链表
    queue <int> Q;//BFS神器
    int level[100010];//BFS标号
    int n,m;//n个点,m条边
    int S,T;//S开始,T结束
    int BFS()//BFS标号,return 0 表示图不同,无增广路
    {
        while (Q.size()) Q.pop();//清空队列
        memset(level,0,sizeof(level));//必须的
        Q.push(S);//放入源点
        level[S]=1;//标号
        while (Q.size())
        {
            int x = Q.front();//取出x
            Q.pop();//弹点
            if (x==T) return 1;//搜到T
            int siz = f[x].size();//搜索所有的路径
            repeat(i,0,siz-1,1)
            {
                if (level[f[x][i].v]==0 && f[x][i].flow)//level=0表示未搜到,f[x][i].flow表示流量
                {
                    level[f[x][i].v]=level[x]+1;//标记下一个点
                    Q.push(f[x][i].v);
                }
            }
        }
        return 0;
    }
    int DFS(int u,int maxflow)//寻找可增广路径
    {
        if (u==T) return maxflow;//找到
        int ret=0;
        int siz = f[u].size();//搜索所有路径
        repeat(i,0,siz-1,1)
        {
            int v = f[u][i].v;
            int flow = f[u][i].flow;
            if (level[u]+1==level[v] && flow > 0)//必须保证的,流量必须大于零
            {
                int MIN = min(maxflow-ret,flow);//找到最大流
                flow = DFS(v,MIN);
                f[u][i].flow -= flow;//减流量
                f[f[u][i].v][f[u][i].by].flow += flow;//连反边
                ret += flow;//加流量
                if (ret==maxflow) return ret;//已经最大
          	}
        }
        return ret;
    }
    int dinic()
    {
        int ans=0;
        while (BFS()) ans += DFS(S,100000000);//如果有可增广路径就继续找
        return ans;
    }
    int main()
    {
        edge empty;//奇怪的操作
        cin >> n >> m >> S >> T;
        repeat(i,1,m,1)
        {
            int tp1,tp2,tp3;
            cin >> tp1 >> tp2 >> tp3;//
            f[tp1].push_back(empty);
            f[tp2].push_back(empty);
            int siz1 = f[tp1].size();
            int siz2 = f[tp2].size();
            f[tp1][siz1-1].v = tp2;//      |
            f[tp1][siz1-1].flow = tp3;//   |
            f[tp1][siz1-1].by = siz2-1;//  V
            f[tp2][siz2-1].v = tp1;//  --->奇怪的加边
            f[tp2][siz2-1].flow = 0;//     ^
            f[tp2][siz2-1].by = siz1-1;//  |
        }
        cout << dinic();//愉快的输出
    }
    
    
  • 相关阅读:
    获得随机数
    Android Studio中的神操作
    Android Studio中的神操作
    我的github首页
    我的github首页
    初步尝试kotlin
    初步尝试kotlin
    创建自己的github博客
    js方法重载
    【HPU】[1014]【C语言训练】亲密数
  • 原文地址:https://www.cnblogs.com/dgklr/p/11166315.html
Copyright © 2020-2023  润新知