COGS[13] 运输问题4

  费用流模板。

  交了并且AC后,才发现我直接忽略了题目输入的 s 和 t,所有点都是按起点1,终点n跑的,结果居然......

 

// q.c

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
const int M=100+10,INF=(int)1e8;
/*********************************************************************************************/
struct Edge {
	int u,v,nex,flow,cap,cost; Edge() {}
	Edge(int a,int b,int c,int d,int e,int f):u(a),v(b),nex(c),flow(d),cap(e),cost(f) {}
}ed[M*M<<1];
int cnt,head[M];
void add_edge(int a,int b,int c,int d) {
	ed[cnt]=Edge(a,b,head[a],0,c, d); head[a]=cnt++;
	ed[cnt]=Edge(b,a,head[b],0,0,-d); head[b]=cnt++;
}
/*********************************************************************************************/
int n,S,T,dis[M],pre[M],lim[M]; bool in[M]; queue<int> Q;
bool spfa(int &Flow,int &Cost) {
	int u,i; Edge e;
	for(i=1;i<=n;i++) dis[i]=lim[i]=INF,pre[i]=in[i]=0;
	dis[S]=0,in[S]=1; Q.push(S);
	while(!Q.empty()) {
		u=Q.front(); Q.pop(); in[u]=0;
		for(i=head[u];~i;i=ed[i].nex) {
			e=ed[i];
			if(e.cap>e.flow&&dis[u]+e.cost<dis[e.v]) {
				dis[e.v]=dis[u]+e.cost,pre[e.v]=i;
				lim[e.v]=min(lim[u],e.cap-e.flow);
				if(!in[e.v]) in[e.v]=1,Q.push(e.v);
			}
		}
	}
	if(lim[T]==INF) return false;
	Flow+=lim[T];
	Cost+=lim[T]*dis[T];
	u=T;
	while(u!=S) {
		i=pre[u],e=ed[i];
		ed[i].flow+=lim[T];
		ed[i^1].flow-=lim[T];
		u=ed[i].u;
	}
	return true;
}
int solve(int s,int t) {
	S=s,T=t; int Flow=0,Cost=0;
	for(;spfa(Flow,Cost););
	return Cost;
}
/*********************************************************************************************/
int main() {
	freopen("maxflowd.in","r",stdin);
	freopen("maxflowd.out","w",stdout);
	memset(head,-1,sizeof(head));
	int s,t,a,b;
	scanf("%d%d%d",&n,&s,&t);
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) {
		scanf("%d%d",&a,&b);
		if(a) add_edge(i,j,a,b);
	}
	//printf("%d\n",solve(1,n));
	printf("%d\n",solve(s,t));
	return 0;
}

 

posted @ 2018-04-21 10:59  qjs12  阅读(73)  评论(0编辑  收藏  举报