bzoj1927 星际竞速 费用流

       据说这是最小路径覆盖问题??反正我这么弱是不知道。

       实际上,由于边是有方向的,所以如果对于任意一个点,只要入度=1,出度=1,就一定能保证满足题意。那么,我们只需要让每个点保证它去向的点只有1个,然后考虑它的前驱即可。

       那么,如果令x表示该点是出发向其它的,x'表示到达的,则构图如下:

1.瞬移:从S->x',流量为1,费用为瞬移的花费;

2.航道x->y:从x->y',流量为1,费用为航道花费;

3.显然任意x必须要有流量才能出发,且只能出发去一个地方,故:S->x,流量为1,费用为0;

4.显然任意x'的入度为1,但上述条件无法保证,古:x'->T,流量为1,费用为0;

       这样任意最大流都是一个合法的方案,最有解即最小费用最大流。

AC代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 60005
#define inf 1000000000
using namespace std;

int n,m,tot=1,sta,ans,gol,fst[N],pnt[N],len[N],cst[N],nxt[N],d[N],e[N],h[N]; bool vis[N];
void add(int aa,int bb,int cc,int dd){
	pnt[++tot]=bb; len[tot]=cc; cst[tot]=dd; nxt[tot]=fst[aa]; fst[aa]=tot;
}
bool spfa(){
	memset(vis,0,sizeof(vis)); int i;
	for (i=sta; i<=gol; i++) d[i]=inf; d[sta]=0;
	int head=0,tail=1; h[1]=sta;
	while (head<tail){
		head=head%(N-5)+1; int x=h[head],p; vis[x]=0;
		for (p=fst[x]; p; p=nxt[p]) if (len[p]){
			int y=pnt[p];
			if (d[x]+cst[p]<d[y]){
				d[y]=d[x]+cst[p];  if (vis[y]) continue;
				vis[y]=0; tail=tail%(N-5)+1; h[tail]=y; e[y]=p;
			}
		}
	}
	return d[gol]<inf;
}
void updata(){
	int i,tmp=inf;
	for (i=gol; i!=sta; i=pnt[e[i]^1]) tmp=min(tmp,len[e[i]]);
	ans+=tmp*d[gol];
	for (i=gol; i!=sta; i=pnt[e[i]^1]){
		len[e[i]]-=tmp; len[e[i]^1]+=tmp;
	}
}
int main(){
	scanf("%d%d",&n,&m); int i;
	sta=0; gol=n<<1|1;
	for (i=1; i<=n; i++){
		int x; scanf("%d",&x); add(0,i+n,1,x); add(i+n,0,0,-x);
		add(0,i,1,0); add(i,0,0,0); add(i+n,gol,1,0); add(gol,i+n,0,0);
	}
	for (i=1; i<=m; i++){
		int x,y,z; scanf("%d%d%d",&x,&y,&z);
		if (x>y) swap(x,y); add(x,y+n,1,z); add(y+n,x,0,-z);
	}
	while (spfa()) updata(); printf("%d\n",ans);
	return 0;
}

by lych

2016.2.3

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值