码迷,mamicode.com
首页 > 其他好文 > 详细

hiho 第116周,最大流最小割定理,求最小割集S,T

时间:2016-10-03 19:33:35      阅读:365      评论:0      收藏:0      [点我收藏+]

标签:

 

 

技术分享
#include <bits/stdc++.h>

using namespace std;

#define maxn 505
#define INF 0x3f3f3f3f

struct Edge
{
    int from,to,cap,flow;
};

struct Dinic
{
    int n,m,s,t;
    vector<Edge> edge;
    vector<int> G[maxn];
    bool vis[maxn];
    int d[maxn];
    int cur[maxn];
    void addEdge (int from,int to,int cap)
    {
        edge.push_back((Edge){from,to,cap,0});
        edge.push_back((Edge){to,from,0,0});
        m = edge.size();
        G[from].push_back(m-2);
        G[to].push_back(m-1);
    }

    bool BFS()
    {
        memset(vis,0,sizeof(vis));
        queue<int> Q;
        Q.push(s);
        d[s] = 0;
        vis[s] = 1;
        while(!Q.empty())
        {
            int x = Q.front();
            Q.pop();
            for(int i=0; i<G[x].size(); i++)
            {
                Edge & e = edge[G[x][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    vis[e.to] = 1;
                    d[e.to] = d[x] + 1;
                    Q.push(e.to);
                }
            }
        }
        return vis[t];
    }

    int DFS(int x,int a)
    {
        if(x==t||a==0) return a;
        int flow = 0,f;
        for(int & i = cur[x]; i<G[x].size(); i++)
        {
            Edge & e = edge[G[x][i]];
            if(d[x] + 1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
            {
                e.flow +=f;
                edge[G[x][i]^1].flow -=f;
                flow +=f;
                a-=f;
                if(a==0) break;
            }
        }
        return flow;
    }

    int Maxflow (int s,int t) {
        this->s = s;this->t = t;
        int flow = 0;
        while(BFS()) {
            memset(cur,0,sizeof(cur));
            flow+=DFS(s,INF);
        }
        return flow;
    }

    //求最小割S,T;
    void new_BFS(int s,int n)
    {
        memset(vis,0,sizeof(vis));
        d[s] = 0;
        vis[s] = 1;
        queue<int> Q;
        Q.push(s);
        while(!Q.empty())
        {
            int u = Q.front();
            Q.pop();
            for(int i=0;i<G[u].size();i++)
            {
                Edge & e = edge[G[u][i]];
                if(!vis[e.to]&&e.cap>e.flow)
                {
                    vis[e.to] = 1;
                    d[e.to] = d[u] + 1;
                    Q.push(e.to);
                }
            }
        }

        int cnt = 0;
        for(int i=1;i<=n;i++)
        {
            if(vis[i]) cnt++;
        }
        printf("%d\n",cnt);
        for(int i=1;i<=n;i++)
            if(vis[i]) printf("%d ",i);
        puts("");
    }

}sol;


int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=0;i<m;i++) {
        int u,v,cap;
        scanf("%d%d%d",&u,&v,&cap);
        sol.addEdge(u,v,cap);
    }
    printf("%d ",sol.Maxflow(1,n));
    sol.new_BFS(1,n);
    return 0;
}
View Code

 

hiho 第116周,最大流最小割定理,求最小割集S,T

标签:

原文地址:http://www.cnblogs.com/TreeDream/p/5929429.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!