无源无汇有上下界可行流

Loj115模板

注意建图

code:

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int inf=1e10;
const int N=300;
const int M=3e4;
struct node{int y,n,v,l;}e[M];
int lin[M],d[N],D[N],cur[N],pls[N],len=1,sum=0,maxflow=0,S,T,n,m,l,r,x,y;
void read(int x,int y,int v,int l)
{e[++len].y=y,e[len].v=v,e[len].l=l,e[len].n=lin[x],lin[x]=len;}
void add(int x,int y,int v,int l)
{read(x,y,v,l);read(y,x,0,l);}
bool bfs(int S){//构建分层图 
	queue<int> q;
	memset(d,0,sizeof(d));
	d[S]=1,q.push(S);
	while(q.size()){
		int x=q.front();q.pop();
		for(int i=lin[x];i;i=e[i].n){
			int y=e[i].y;
			if(d[y]||!e[i].v)continue;
			d[y]=d[x]+1;
			q.push(y);
		}
	}
	return d[T]>0;
}
int dfs(int x,int minf){//minf为可以流到该点的流量 
	int sum=0,flow=0;//sum为该点可以流出的流量之和 
	if(x==T)return minf;
	for(int &i=cur[x];i;i=e[i].n){//当前弧优化 
		int y=e[i].y;
		if(d[y]==d[x]+1&&e[i].v){
			flow=dfs(y,min(minf,e[i].v));
			if(!flow)d[y]=0;//如果y向后不能再流了,就炸掉y点 
			sum+=flow,minf-=flow,e[i].v-=flow,e[i^1].v+=flow;//更新 
			if(!minf)return sum;//如果前面的都流完了,直接返回 
		}
	}return sum;
}
void dinic(){
	while(bfs(S)){
		rep(i,1,n)cur[i]=lin[i];
		maxflow+=dfs(S,inf);
	}
}
int main()
{
	scanf("%d%d",&n,&m);S=n+1,T=S+1;
	rep(i,1,m){scanf("%d%d%d%d",&x,&y,&l,&r);add(x,y,r-l,l);D[y]+=l,D[x]-=l;}
	rep(i,1,n)if(D[i]>0)add(S,i,D[i],0);else add(i,T,-D[i],0);
	dinic();
	for(int i=lin[S];i;i=e[i].n){
		if(e[i].v){
			puts("NO");
			return 0;
		}
	}
	printf("YES\n");
	rep(i,1,m)
	printf("%d\n",e[i*2+1].v+e[i*2+1].l);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/strangeDDDF/article/details/85782985