模板-Dinic

const int INF=1e9;
const int maxn=;
const int maxm=;

int n,m,s,t,num,adj[maxn],dis[maxn],q[maxn];  
struct edge{
    int v,w,pre;  
}e[maxm];  
void insert(int u,int v,int w){
    e[num]=(edge){v,w,adj[u]};  
    adj[u]=num++;  
    e[num]=(edge){u,0,adj[v]};  
    adj[v]=num++;  
}  
int bfs()  
{  
    int i,x,v,tail=0,head=0;  
    memset(dis,0,sizeof(dis));  
    dis[s]=1;  
    q[tail++]=s;  
    while(head<tail)  
    {  
        x=q[head++];          
        for(i=adj[x];i!=-1;i=e[i].pre)  
            if(e[i].w&&dis[v=e[i].v]==0)  
            {  
                dis[v]=dis[x]+1;  
                if(v==t)  
                    return 1;  
                q[tail++]=v;  
            }  
    }  
    return 0;  
}  
int dfs(int s,int limit)  
{  
    if(s==t)  
        return limit;  
    int i,v,tmp,cost=0;  
    for(i=adj[s];i!=-1;i=e[i].pre)  
        if(e[i].w&&dis[s]==dis[v=e[i].v]-1)  
        {  
            tmp=dfs(v,min(limit-cost,e[i].w));  
            if(tmp>0)  
            {  
                e[i].w-=tmp;  
                e[i^1].w+=tmp;  
                cost+=tmp;  
                if(limit==cost)  
                    break;  
            }  
            else dis[v]=-1;  
        }  
    return cost;  
}  
int Dinic()  
{  
    int ans=0;  
    while(bfs())  
        ans+=dfs(s,INF);  
    return ans;  
} 

void init(){
	memset(adj,-1,sizeof(adj));  
    num=0;  
    s=;  
    t=;
}


白书上的。

struct Dinic
{
	struct Edge{int from,to,cap,flow;};
	vector<Edge> edges;
	//边表。edges[e]和edges[e+1]互为反向弧,
	//注意到e必须是偶数即是大的奇数与比他小的偶数互为反向边,即e与e^1互为反向边
	vector<int> G[size_num];
	//领接表,G[i][j]表示节点i的第j条边在e数组中的序号
	void add_edge(int from,int to,int cap)
	{
		edges.push_back((Edge){from,to,cap,0});//加入正向边
		edges.push_back((Edge){to,from,0,0});//加入反向边
		int m=edges.size();
		G[from].push_back(m-2);//存的是边的位子
		G[to].push_back(m-1);//貌似有一种静态链表的感觉
	}
	int s,t;//源点编号和汇点编号
	bool vis[size_num];//bfs时使用
	int d[size_num];//从起点到i的距离
	int cur[size_num];//当前弧的下标
	void init()
	{
		edges.clear();
		for(int i=0;i<size_num;i++)
		G[i].clear();
	}
	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];
	}

	//dfs
	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 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;
	}
}solve;


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值