最大流算法(Ford-Fulkerson)

来源:互联网 发布:千股跌停 知乎 编辑:程序博客网 时间:2024/05/16 10:34

适合点比较少的(V<1000)

struct edge{    int to,cap,rev;//终点,容量,反向边};vector<edge>G[N];//图的邻接矩阵表示bool used[N];//dfs中用到的访问标记//向图中增加一条从s到t容量为cap的边void addedge(int u,int v,int w){    G[u].push_back((edge){v,w,G[v].size()});    G[v].push_back((edge){u,0,G[u].size()-1});//如果是无向图,只要把0改成w即可}int dfs(int v,int t,int f){    if(v==t)        return f;    used[v]=true;    for(int i=0;i<G[v].size();i++)    {        edge &e=G[v][i];        if(!used[e.to]&&e.cap>0)        {            int d=dfs(e.to,t,min(f,e.cap));            if(d>0)            {                e.cap-=d;                G[e.to][e.rev].cap+=d;                return d;            }        }    }    return 0;}//求解从s到t上的最大流int max_flow(int s,int t){    int flow=0;    for(;;)    {        memset(used,0,sizeof(used));        int f=dfs(s,t,INF);        if(f==0)            return flow;        flow+=f;    }}void Init(){    for(int i=0;i<N;i++)        G[i].clear();}

适合点多的

struct Node{    int x,y,id;}node[N];struct edge{    int to,cap,rev;//终点,容量,反向边};vector<edge>G[N];//图的邻接矩阵表示bool used[N];//dfs中用到的访问标记int level[N];//顶点到源点的距离标号int iter[N];//当前弧,在其之前的边已经没用了bool cmp(Node a,Node b){    if(a.x==b.x)        return a.y>b.y;    else        return a.x<b.x;}//向图中增加一条从s到t容量为cap的边void addedge(int u,int v,int w){    G[u].push_back((edge){v,w,G[v].size()});    G[v].push_back((edge){u,0,G[u].size()-1});//如果是无向图,只要把0改成w即可}//通过bfs计算从源点出发的距离标号void bfs(int s){    memset(level,-1,sizeof(level));    queue<int> que;    level[s]=0;    que.push(s);    while(!que.empty())    {        int v=que.front();        que.pop();        for(int i=0;i<G[v].size();i++)        {            edge &e=G[v][i];            if(e.cap>0&&level[e.to]<0)            {                level[e.to]=level[v]+1;                que.push(e.to);            }        }    }}//通过dfs寻找增广路径int dfs(int v,int t,int f){    if(v==t)        return f;    for(int &i=iter[v];i<G[v].size();i++)    {        edge &e=G[v][i];        if(e.cap>0&&level[v]<level[e.to])        {            int d=dfs(e.to,t,min(f,e.cap));            if(d>0)            {                e.cap-=d;                G[e.to][e.rev].cap+=d;                return d;            }        }    }    return 0;}//求解从s到t上的最大流int max_flow(int s,int t){    int flow=0;    for(;;)    {        bfs(s);        if(level[t]<0)            return flow;        memset(iter,0,sizeof(iter));        int f;        while((f=dfs(s,t,INF))>0)            flow+=f;    }}void Init(){    for(int i=0;i<N;i++)        G[i].clear();}

同样是比较快的:

int s,t;//超级源点和超级汇点struct Edge{    int from, to, cap, flow;    Edge() {}    Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}};struct ISAP{    int p[N], num[N], cur[N], d[N];    int t, s, n, m;    bool vis[N];    vector<int> G[N];    vector<Edge> edges;    void init(int n)//初始化+获取节点数    {        this->n = n;        for (int i = 0; i <= n; i++)        {            G[i].clear();            d[i] = INF;        }        edges.clear();    }    void AddEdge(int from, int to, int cap)    {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool BFS()    {        memset(vis, 0, sizeof(vis));        queue<int> Q;        d[t] = 0;        vis[t] = 1;        Q.push(t);        while (!Q.empty())        {            int u = Q.front();            Q.pop();            for (int i = 0; i < G[u].size(); i++)            {                Edge &e = edges[G[u][i] ^ 1];                if (!vis[e.from] && e.cap > e.flow)                {                    vis[e.from] = true;                    d[e.from] = d[u] + 1;                    Q.push(e.from);                }            }        }        return vis[s];    }    int Augment()    {        int u = t, flow = INF;        while (u != s)        {            Edge &e = edges[p[u]];            flow = min(flow, e.cap - e.flow);            u = edges[p[u]].from;        }        u = t;        while (u != s)        {            edges[p[u]].flow += flow;            edges[p[u] ^ 1].flow -= flow;            u = edges[p[u]].from;        }        return flow;    }    int Maxflow(int s, int t)    {        this->s = s;        this->t = t;        int flow = 0;        BFS();        if (d[s] > n)            return 0;        memset(num, 0, sizeof(num));        memset(cur, 0, sizeof(cur));        for (int i = 0; i < n; i++)            if (d[i] < INF)                num[d[i]]++;        int u = s;        while (d[s] <= n)        {            if (u == t)            {                flow += Augment();                u = s;            }            bool ok = false;            for (int i = cur[u]; i < G[u].size(); i++)            {                Edge &e = edges[G[u][i]];                if (e.cap > e.flow && d[u] == d[e.to] + 1)                {                    ok = true;                    p[e.to] = G[u][i];                    cur[u] = i;                    u = e.to;                    break;                }            }            if (!ok)            {                int Min = n ;                for (int i = 0; i < G[u].size(); i++)                {                    Edge &e = edges[G[u][i]];                    if (e.cap > e.flow)                        Min = min(Min, d[e.to]);                }                if (--num[d[u]] == 0)                    break;                num[d[u] = Min + 1]++;                cur[u] = 0;                if (u != s)                    u = edges[p[u]].from;            }        }        return flow;    }};
原创粉丝点击