Bzoj:[ZJOI2010]network 网络扩容:网络流,最大流+费用流

题目链接:1834:[ZJOI2010]network 网络扩容

好端端的一道水题让我给做的……

一开始我想的是先跑一边dinic得到残量网络,反正K不大然后就跑K遍费用流,每次跑费用流时碰到一条正向边没流满就把边权设为0,否则流量+1,边权为最开始的权值

但是这样傻X都能看出来是错的QAQ

加入跑了一遍费用流以后我们流量加过1的边并没有流到,那么他的权值就成0了,成0了,成0了……然后就GG了……

我还满心欢喜的写了半天,错了还以为是模板打错了QAQ

荏弱没话说……

这题我们一遍dinic后对于剩余图,只要这张图上的边是正边就复制一条容量为inf费用不变,反向边复制一条容量为0费用相反,并把原来的边的边权改为0

注意是复制原来的边保留,这样再次跑的时候由于原来的剩余边费用都为0会被优先选择

于是就对了……我还是太naive……

#include
#include
#include
#include
#include
#include
using namespace std;
const int maxn=2000+10;
const int inf=0x7fffffff/2-1;
int n,m,h[maxn],tot=1,S,T,K,vis[maxn];
struct edge{int to,next,w,c,f;}G[maxn*10];
int dis[maxn],pre[maxn],cur[maxn];

bool bfs(){
	for (int i=S;i<=T;++i) vis[i]=-1;
	queueq; q.push(S); vis[S]=0;
	while (!q.empty()){
		int u=q.front(); q.pop();
		for (int i=h[u];i;i=G[i].next){
			int v=G[i].to;
			if (vis[v]==-1&&G[i].c>0){
				vis[v]=vis[u]+1; q.push(v);
			}
		}
	}return vis[T]!=-1;
}

int dfs(int x,int f){
	if (x==T||f==0) return f;
	int w,used=0;
	for (int i=cur[x];i;i=G[i].next)
	    if (G[i].c&&vis[x]+1==vis[G[i].to]){
			w=f-used;
			w=dfs(G[i].to,min(w,G[i].c));
			G[i].c-=w; G[i^1].c+=w;
			used+=w; if (used==f) return f;
			if (G[i].c) cur[x]=i;
	    }
	if (!used) vis[x]=-1;
	return used;
}

void dinic(){
	int ret=0;
	while (bfs()){
		for (int i=S;i<=T;++i) cur[i]=h[i];
		ret+=dfs(S,inf);
	}printf("%d ",ret);
}

void add(int x,int y,int c,int w){
	G[++tot].to=y; G[tot].next=h[x]; h[x]=tot;
	G[tot].c=c; G[tot].w=w; G[tot].f=x;
}

void rebuild(){
	int sum=tot; S=0; add(S,1,K,0); add(1,S,0,0);
	for (int i=2;i<=sum;++i)
		if (!(i&1)) add(G[i].f,G[i].to,inf,G[i].w),
					add(G[i].to,G[i].f,0,-G[i].w),
					G[i].w=G[i^1].w=0;
}

bool spfa(){
	for (int i=S;i<=T;++i){vis[i]=0;dis[i]=inf;pre[i]=-1;}
	vis[S]=1; dis[S]=0; dequeq; q.push_front(S);
	while (!q.empty()){
		int u=q.front(); q.pop_front(); vis[u]=0;
		for (int i=h[u];i;i=G[i].next){
			int v=G[i].to;
			if (dis[v]>dis[u]+G[i].w&&G[i].c>0){
				dis[v]=dis[u]+G[i].w;
				pre[v]=i; if (!vis[v]){ vis[v]=1;
					if (!q.empty()&&dis[v]


你可能感兴趣的:(OI,网络流)