[bzoj1003] [ZJOI2006]物流运输trans

不难想到本题的方程为f[i]=min(min(f[j]+cover(j+1,i)*(i-j)+k)(0<j<i),cover(1,i)*i(j=0)),其中cover(x,y)为若第x天到第y天走相同的路的最短路(注意cover(x,y)可能并不存在!!)

之后的就是实现的问题了,由于最近非常不仔细,连一道最裸的完全背包题都因为输入输出调上30+分钟,故代码很挫,各位神犇不要鄙视...

const
	MAXM=20;
	MAXN=100;
var
	l,n,m,k,e,d:longint;
	ed,cost,pre:array[1..500]of longint;
	last:array[1..MAXM]of longint;
	fbd:array[1..MAXN,0..MAXM]of longint;
	f:array[0..MAXN]of longint;
	dis:Array[1..MAXM]of longint;
	h,hash:array[1..MAXM]of boolean;
procedure add(x,y,z:longint);
begin
	inc(l);
	ed[l]:=y;cost[l]:=z;
	pre[l]:=last[x];last[x]:=l;
end;
procedure init;
var i,j,x,y,z:longint;
begin
	l:=0;
	readln(n,m,k,e);
	for i:=1 to e do
	begin
		readln(x,y,z);
		add(x,y,z);
		add(y,x,z);
	end;
	readln(d);
	for i:=1 to d do
	begin
		readln(x,y,z);
		for j:=y to z do
		begin
			inc(fbd[j][0]);
			fbd[j][fbd[j][0]]:=x;
		end;
	end;
end;
function cover(x,y:longint):longint;
var i,j,v,min,top:longint;
begin
	fillchar(h,sizeof(h),0);
	fillchar(hash,sizeof(hash),0);
	top:=m;
	for i:=x to y do
		for j:=1 to fbd[i][0] do
		if(not hash[fbd[i][j]])then
		begin
			dec(top);hash[fbd[i][j]]:=true;
		end;
	for i:=1 to m do dis[i]:=maxlongint;
	dis[1]:=0;
	for i:=1 to top-1 do
	begin
		min:=maxlongint;v:=-1;
		for j:=1 to m do
		if(not (hash[j] or h[j]))and(dis[j]<min)then
		begin
			v:=j;min:=dis[j];
		end;
		h[v]:=true;
		j:=last[v];
		while(j>0)do
		begin
			if(not(hash[ed[j]] or h[ed[j]]))and(dis[ed[j]]>dis[v]+cost[j])then
				dis[ed[j]]:=dis[v]+cost[j];
			j:=pre[j];
		end;
	end;
	exit(dis[m]);
end;
function min(a,b:longint):longint;
begin
	if(a>b)then exit(b) else exit(a);
end;
procedure dp;
var i,j,t:longint;
begin
	for i:=1 to n do
	begin
		f[i]:=cover(1,i);
		if(f[i]<>maxlongint)then f[i]:=f[i]*i;
		for j:=1 to i-1 do
		begin
			t:=cover(j+1,i);
			if(t<>maxlongint)then
			begin
				f[i]:=min(f[i],f[j]+t*(i-j)+k);
			end;
		end;
	end;
	writeln(f[n]);
end;
begin
	init;
	dp;
end.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值