1. 程式人生 > >網路流、費用流 板

網路流、費用流 板

容量為K的最大費用最大流

struct edge{
	int from,to,cap,cost,next;
	edge(int u=0,int v=0,int c=0,int m=0,int f=0):from(u),to(v),cap(c),cost(m),next(f){}
}side[maxm];
int head[maxn];
int cnt,ans,maxflow;
int s,t,n,k;
int incf[maxn],dis[maxn],pre[maxn],vis[maxn];

void add(int u,int v,int w,int c)
{
    side[cnt]=edge(u,v,w,c,head[u]);head[u]=cnt++;
    side[cnt]=edge(v,u,0,-c,head[v]);head[v]=cnt++;
}
bool spfa()
{
	memset(dis,0xcf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int>q;
	q.push(s);
	dis[s]=0;
	vis[s]=1;
	incf[s]=1<<30;
	while(q.size()){
		int x = q.front();
		vis[x]=0;
		q.pop();
		for(int i = head[x]; i != -1; i = side[i].next){
			int y =side[i].to;
			if(side[i].cap){
				if(dis[x]+side[i].cost>dis[y]){
					dis[y] = dis[x] + side[i].cost;
					//printf("%d %d %d %d %d\n",x,y,dis[x],dis[y],side[i].cap);
					incf[y] = min(incf[x], side[i].cap);
					pre[y] = i;
					if(!vis[y])
						q.push(y),vis[y]=1;
				}
			}
		}
	}
	return dis[t] != 0xcfcfcfcf;
}

void update()
{
	int x = t;
	while(x != s){
		int i = pre[x];
		side[i].cap -= incf[t];
		side[i^1].cap += incf[t];
		x = side[i^1].to;
	}
	maxflow += incf[t];
	ans += dis[t] * incf[t];
}

不限流量的最小/最大費用流

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

const int maxn = 1000;
const int maxm = 200010;
const int inf = 0x3f3f3f3f;

struct edge{
	int from,to,cap,cost,next;
	edge(int u=0,int v=0,int c=0,int m=0,int f=0):from(u),to(v),cap(c),cost(m),next(f){}
}side[maxm];
int head[maxn];
int cnt;
int s,t;
int incf[maxn],dis[maxn],pre[maxn],vis[maxn];

void add(int u,int v,int w,int c)//from,to,cap,cost
{
    side[cnt]=edge(u,v,w,c,head[u]);head[u]=cnt++;
    side[cnt]=edge(v,u,0,-c,head[v]);head[v]=cnt++;
}
bool spfa()
{
	memset(dis,inf,sizeof(dis));
	memset(vis,0,sizeof(vis));
	queue<int>q;
	q.push(s);
	dis[s]=0;
	vis[s]=1;
	incf[s]=1<<30;
	while(q.size()){
		int x = q.front();
		vis[x]=0;
		q.pop();
		for(int i = head[x]; i != -1; i = side[i].next){
			int y =side[i].to;
			if(side[i].cap > 0&&dis[x]+side[i].cost<dis[y]){
					dis[y] = dis[x] + side[i].cost;
					//printf("%d %d %d %d %d\n",x,y,dis[x],dis[y],side[i].cap);
					incf[y] = min(incf[x], side[i].cap);
					pre[y] = i;
					if(!vis[y])
						q.push(y),vis[y]=1;
				}
		}
	}
	return dis[t] != inf;
}

int update()
{
	int x = t;
	while(x != s){
		int i = pre[x];
		side[i].cap -= incf[t];
		side[i^1].cap += incf[t];
		x = side[i^1].to;
	}
	return dis[t] * incf[t];
}