zoukankan      html  css  js  c++  java
  • 网络流

    最大流

    【模板】网络最大流(洛谷)

    dinic

    int head[MAXN],tot = 1;
    struct edge
    {
    	int v,nxt;LL w;
    }e[MAXM << 1];
    void Add_Edge(int x,int y,LL z)
    {
    	e[++tot].v = y;
    	e[tot].w = z;
    	e[tot].nxt = head[x];
    	head[x] = tot;
    }
    int d[MAXN];
    bool bfs(int s,int t)
    {
    	for(int i = 1;i <= n;++ i) d[i] = -1;
    	d[s] = 0;
    	queue<int> q; q.push(s);
    	while(!q.empty())
    	{
    		int p = q.front(); q.pop();
    		for(int i = head[p]; i ;i = e[i].nxt)
    			if(d[e[i].v] == -1 && e[i].w > 0)
    			{
    				d[e[i].v] = d[p] + 1;
    				q.push(e[i].v);
    			}
    	}
    	return d[t] != -1;
    }
    int cur[MAXN];
    LL dfs(int x,LL flow,int t)
    {
    	if(x == t) return flow;
    	LL ret = 0;
    	for(int &i = cur[x]; i ;i = e[i].nxt)
    	{
    		if(d[x] + 1 == d[e[i].v] && e[i].w > 0)
    		{
    			LL dz = dfs(e[i].v,Min(flow-ret,e[i].w),t);//记得是flow-ret而不是flow!!!(货物变多可还行 
    			e[i].w -= dz; e[i^1].w += dz;
    			if((ret += dz) == flow) break;
    		}
    	}
    	if(!ret) d[x] = -1;
    	return ret;
    }
    LL dinic(int s,int t)
    {
    	LL ret = 0;
    	while(bfs(s,t))
    	{
    		for(int i = 1;i <= n;++ i) cur[i] = head[i];
    		ret += dfs(s,INF,t);
    	}
    	return ret;
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); m = Read(); s = Read(); t = Read();
    	for(int i = 1,u,v,w;i <= m;++ i)
    	{
    		u = Read(),v = Read(),w = Read();
    		Add_Edge(u,v,w);
    		Add_Edge(v,u,0);
    	}
    	Put(dinic(s,t));
    	return 0;
    }
    

    最小费用最大流

    【模板】最小费用最大流(洛谷)

    int head[MAXN],tot = 1;//tot初值一定要是1啊啊啊啊啊啊啊啊啊 
    struct edge
    {
    	int v,w,c,nxt;
    }e[MAXM << 1];
    void Add_Edge(int u,int v,int w,int c)
    {
    	e[++tot].v = v;
    	e[tot].w = w;
    	e[tot].c = c;
    	e[tot].nxt = head[u];
    	head[u] = tot;
    }
    
    int pre[2][MAXN],dis[MAXN],flow[MAXN],maxflow,maxcost;
    bool vis[MAXN];
    bool bfs(int s,int t)
    {
    	for(int i = 1;i <= n;++ i) dis[i] = INF;
    	queue<int> q; q.push(s);
    	flow[s] = INF; dis[s] = 0; 
    	while(!q.empty())
    	{
    		int p = q.front(); q.pop();
    		vis[p]= 0;
    		for(int i = head[p]; i ;i = e[i].nxt)
    		{
    			if(dis[p] + e[i].c < dis[e[i].v] && e[i].w > 0)
    			{
    				dis[e[i].v] = dis[p] + e[i].c;
    				pre[0][e[i].v] = p;
    				pre[1][e[i].v] = i;
    				flow[e[i].v] = Min(flow[p],e[i].w);
    				if(!vis[e[i].v])
    				{
    					vis[e[i].v] = 1;
    					q.push(e[i].v);
    				}
    			}
    		}
    	}
    	return dis[t] != INF;
    }
    void MCMF(int s,int t)
    {
    	while(bfs(s,t))
    	{
    		maxflow += flow[t];
    		maxcost += flow[t] * dis[t];
    		for(int now = t;now != s;now = pre[0][now])
    		{
    			e[pre[1][now]].w -= flow[t];
    			e[pre[1][now]^1].w += flow[t];
    		}
    	}
    }
    
    int main()
    {
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n = Read(); m = Read(); s = Read(); t = Read();
    	for(int i = 1,u,v,w,c;i <= m;++ i)
    	{
    		u = Read(); v = Read(); w = Read(); c = Read();
    		Add_Edge(u,v,w,c);
    		Add_Edge(v,u,0,-c);
    	}
    	MCMF(s,t);
    	Put(maxflow,' '),Put(maxcost);
    	return 0;
    }
    
  • 相关阅读:
    java:找出占用CPU资源最多的那个线程
    vue中的样式穿透
    宽度过小,左右浮动元素会下沉的解决方案
    Object.keys方法之详解
    element UI实现动态生成多级表头
    JavaScript校验身份证,包含省份、长度、出生年月日、校验位的检测、性别、年龄
    JavaScript日期格式化处理
    vue点击编辑按钮,内容变成input可以修改,也可以删除
    NProgress颜色的修改以及在Vue中的使用
    vue中使用raphael.js实现地图绘制
  • 原文地址:https://www.cnblogs.com/PPLPPL/p/14376395.html
Copyright © 2011-2022 走看看