最小费用最大流 模板

class match{
public://最大费用则加边的费用的值正好负号相反的
	//s和t要赋值的,并且花费一个为正一个为负刚好抵消的
	int s,t;//源点和结束点的,开始为1 的
	struct node{
		int y,cost,cap,pre;
	};
	node a[N*1000];
	int dis[N];
	bool vis[N];
	int point[N];
	int len,pre[N];
	void init()
	{
		len=0;
		memset(pre,-1,sizeof(pre));
	}
	void addpage(int x,int y,int cap,int cost)
	{
         a[len].y=y;
		 a[len].pre=pre[x];
		 a[len].cap=cap;
		 a[len].cost=cost;
		 pre[x]=len++;
	}
	bool spfa()
	{
        repf(i,1,t) vis[i]=false,dis[i]=inf;
		vis[s]=true; dis[s]=0;
		queue<int>q;
		q.push(s);
		while(!q.empty())
		{
			int x=q.front(); q.pop();
			vis[x]=false;
			for(int i=pre[x]; i!=-1; i=a[i].pre)
			{
				int y=a[i].y;
				if(a[i].cap && dis[y]>dis[x]+a[i].cost)
				{
                    point[y]=i;//记录边的
					dis[y]=dis[x]+a[i].cost;
					if(vis[y]==false)
					{
						vis[y]=true;
						q.push(y);
					}
				}
			}
		}
		if(dis[t]!=inf) return true;
		else return false;
	}
	int fond()
	{
		int ans=0;
		while(spfa())
		{
			int Min=INT_MAX;
            for(int i=t; i!=s; i=a[point[i]^1].y)//最小的容量,进行扩展的
				Min=min(Min,a[point[i]].cap);
			for(int i=t; i!=s; i=a[point[i]^1].y)
			{
				a[point[i]].cap-=Min;
				a[point[i]^1].cap+=Min;
				ans+=Min*a[point[i]].cost;
			}
		}
		return ans;
	}
};
match sa;

你可能感兴趣的:(最小费用最大流 模板)