网络最大流最短增广路Dinic算法模板

//1是源点,n是汇点。

#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;

const int maxn=1000+10;
const int INF=0x7FFFFFFF;

struct Edge { int from,to,cap,flow; };
vector<Edge>edges;
vector<int>G[maxn];
bool vis[maxn];
int d[maxn];
int cur[maxn];
int n,m,s,t;

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=edges[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];
}

void AddEdge(int from,int to,int cap)
{
    Edge r;
    r.from=from;r.to=to;r.cap=cap;r.flow=0;
    edges.push_back(r);
    Edge d;
    d.from=to;d.to=from;d.cap=0;d.flow=0;
    edges.push_back(d);
    m=edges.size();
    G[from].push_back(m-2);
    G[to].push_back(m-1);
}

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=edges[G[x][i]];
        if(d[x]+1==d[e.to]&&(f=DFS(e.to,min(a,e.cap-e.flow)))>0)
        {
            e.flow+=f;
            edges[G[x][i]^1].flow-=f;
            flow+=f;
            a-=f;
            if(a==0) break;
        }
    }
    return flow;
}

int Maxflow(int ss,int tt)
{
    int flow=0;
    while(BFS())
    {
        memset(cur,0,sizeof(cur));
        flow+=DFS(ss,INF);
    }
    return flow;
}

int main()
{
    int T,ii;
    scanf("%d",&T);
    for(ii=1;ii<=T;ii++)
    {
        edges.clear();
        for(int i=0;i<maxn;i++) G[i].clear();
        int mm;
        scanf("%d%d",&n,&mm);
        s=1;t=n;
        while(mm--)
        {
            int uu,vv,cc;
            scanf("%d%d%d",&uu,&vv,&cc);
            AddEdge(uu,vv,cc);
        }
        printf("Case %d: %d\n",ii,Maxflow(s,t));
    }
    return 0;
}
时间: 2024-11-10 21:16:50

网络最大流最短增广路Dinic算法模板的相关文章

关于最短增广路算法和连续最短增广路算法的操作步骤

最短增广路算法(SAP): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中不断用BFS增广,直到层次网络中没有增广路为止:每次增广完毕,在层次网络中要去掉因改进流量而导致饱和的弧: 4.转到步骤(2). 连续最短增广路算法(Dinic): 1.初始化容量网络和网络流: 2.构造残留网络和层次网络,如果汇点不在层次网络中,则算法结束: 3.在层次网络中用一次DFS过程进行增广,DFS执行完毕,该阶段的增广也执行完毕: 4.转到步骤(

网络流之 最短增广路算法模板(SAP)

数据输入格式:首先输入顶点个数n和弧数m,然后输入每条弧的数据.规定源点为顶点0,汇点为顶点n-1.每条弧的数据格式为:u,v,w,分别表示这条弧的起点,终点,容量.顶点序号从0开始. 代码: 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <cmath> 6 #include <string&g

最大流增广路(KM算法) HDOJ 2255 奔小康赚大钱

题目传送门 1 /* 2 KM:裸题第一道,好像就是hungary的升级版,不好理解,写点注释 3 KM算法用来解决最大权匹配问题: 在一个二分图内,左顶点为X,右顶点为Y,现对于每组左右连接Xi,Yj有权w(i,j), 4 求一种匹配使得所有w(i,j)的和最大.也就是最大权匹配一定是完备匹配.如果两边的点数相等则是完美匹配. 5 如果点数不相等,其实可以虚拟一些点,使得点数相等,也成为了完美匹配.最大权匹配还可以用最大流去解决 6 */ 7 #include <cstdio> 8 #inc

最大流增广路(KM算法) HDOJ 1533 Going Home

题目传送门 1 /* 2 最小费用流:KM算法是求最大流,只要w = -w就可以了,很经典的方法 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 int x

最大流增广路(KM算法) HDOJ 1853 Cyclic Tour

题目传送门 1 /* 2 KM: 相比HDOJ_1533,多了重边的处理,还有完美匹配的判定方法 3 */ 4 #include <cstdio> 5 #include <cmath> 6 #include <algorithm> 7 #include <cstring> 8 using namespace std; 9 10 const int MAXN = 1e2 + 10; 11 const int INF = 0x3f3f3f3f; 12 int x

hdu 3549 Flow Problem 增广路ford-fullkerson算法

#include<stdio.h> #include<string.h> #include<queue> #include<vector> #include<algorithm> using namespace std; const int N=1024*2; const int inf=1<<24; struct arc { int c,f; } g[N][N]; int n,m,i,j,u,v,c,f; int abs(int x

POJ 3469.Dual Core CPU 最大流dinic算法模板

Dual Core CPU Time Limit: 15000MS   Memory Limit: 131072K Total Submissions: 24830   Accepted: 10756 Case Time Limit: 5000MS Description As more and more computers are equipped with dual core CPU, SetagLilb, the Chief Technology Officer of TinySoft C

网络最大流增广路模板(EK &amp; Dinic)

EK算法: int fir[maxn]; int u[maxm],v[maxm],cap[maxm],flow[maxm],nex[maxm]; int e_max; int p[maxn],q[maxn],d[maxn]; void add_edge(int _u,int _v,int _w) { int e; e=e_max++; u[e]=_u;v[e]=_v;cap[e]=_w; nex[e]=fir[u[e]];fir[u[e]]=e; e=e_max++; u[e]=_v;v[e]=

最大流——增广路算法

关于网络流的增广路算法,网上有很多详细介绍,这里是摘录的模板.详细请见:http://www.cnblogs.com/kuangbin/archive/2011/07/26/2117636.html 1 #include<iostream> 2 #include<iomanip> 3 #include<ctime> 4 #include<climits> 5 #include<algorithm> 6 #include<queue>