BZOJ1001题解

8 篇文章 0 订阅

嗯A了一道BZOJ上的题> <

好开森呐什么的。。

就是平面图的最小割就是它的对偶图的最短路

听上去很高大上。。其实就是把平面图的那个中间的空空的那个小洞当成一个点,然后两个小洞之间的夹着的那条边的权值就是那两个点之间线的权值

然后注意n=1和m=1的情况

妈蛋被这个坑了好久

Code:

var	heap,d,where,headlist:array[0..2000002] of longint;
	next,t,weight:array[0..5000002] of longint;
	nothing,tot,step,top,step1,step2,num,x,i,j,k,n,m:longint;
function min(A,b:longint):longint;
begin
	if a<b then exit(a);
	exit(b);
end;
procedure ten;
begin
	tot:=maxlongint;
	for i:=1 to m-1 do begin
						read(d[i]);
						tot:=min(tot,d[i]);
					   end;
	writeln(tot);
	halt;
end;
procedure tem;
begin
	tot:=maxlongint;
	for i:=1 to n-1 do begin
						read(d[i]);
						tot:=min(tot,d[i]);
					   end;
	writeln(tot);
	halt;
end;
procedure init;
begin
	readln(n,m);
	if n=1 then ten;
	if m=1 then tem;
	for i:=0 to 2*(n-1)*(m-1)+1 do headlist[i]:=-1;
	for j:=1 to m-1 do
	begin
		read(x);
		step1:=2*(n-1)*(m-1)+1;
		step2:=2*j;
		inc(num);
		next[num]:=headlist[step2];
		headlist[step2]:=num;
		t[num]:=step1;
		weight[num]:=x;
	end;
	for i:=2 to n-1 do
		for j:=1 to m-1 do
		begin
			read(x);
			step1:=(i-1)*2*(m-1)+j*2;
			step2:=step1-(2*(m-1)+1);
			inc(num);
			next[num]:=headlist[step1];
			headlist[step1]:=num;
			t[num]:=step2;
			weight[num]:=x;
			inc(num);
			next[num]:=headlist[step2];
			headlist[step2]:=num;
			t[num]:=step1;
			weight[num]:=x;
		end;
	for j:=1 to m-1 do
	begin
		read(x);
		step1:=0;
		step2:=(n-2)*2*(m-1)+1+(j-1)*2;
		inc(num);
		next[num]:=headlist[step1];
		headlist[step1]:=num;
		t[num]:=step2;
		weight[num]:=x;
	end;
	for i:=1 to n-1 do
	begin
		read(x);
		step1:=0;
		step2:=(i-1)*2*(m-1)+1;
		inc(num);
		next[num]:=headlist[step1];
		headlist[step1]:=num;
		t[num]:=step2;
		weight[num]:=x;
		for j:=2 to m-1 do
		begin
			read(x);
			step1:=(i-1)*2*(m-1)+(j-1)*2;
			step2:=step1+1;
			inc(num);
			next[num]:=headlist[step1];
			headlist[step1]:=num;
			t[num]:=step2;
			weight[num]:=x;
			inc(num);
			next[num]:=headlist[step2];
			headlist[step2]:=num;
			t[num]:=step1;
			weight[num]:=x;
		end;
		read(x);
		step1:=2*i*(m-1);
		step2:=2*(n-1)*(m-1)+1;
		inc(num);
		next[num]:=headlist[step1];
		headlist[step1]:=num;
		t[num]:=step2;
		weight[num]:=x;
	end;
	for i:=1 to n-1 do
		for j:=1 to m-1 do
		begin
			read(x);
			step1:=(i-1)*2*(m-1)+1+(j-1)*2;
			step2:=step1+1;
			inc(num);
			next[num]:=headlist[step1];
			headlist[step1]:=num;
			t[num]:=step2;
			weight[num]:=x;
			inc(num);
			next[num]:=headlist[step2];
			headlist[step2]:=num;
			t[num]:=step1;
			weight[num]:=x;
		end;
end;
procedure sert(a:longint);
var fa:longint;
begin
	if a=1 then exit;
	fa:=a shr 1;
	if d[heap[fa]]>d[heap[a]] then begin
									where[heap[fa]]:=a;
									where[heap[a]]:=fa;
									step:=heap[a];
									heap[a]:=heap[fa];
									heap[fa]:=step;
									sert(fa);
								   end;
end;
procedure down(a:longint);
var son1,son2:longint;
begin
	son1:=a shl 1;
	son2:=a shl 1+1;
	if son1>top then exit;
	if son1=top then
					if d[heap[a]]>d[heap[son1]] then begin
														where[heap[a]]:=son1;
														where[heap[son1]]:=a;
														step:=heap[a];
														heap[a]:=heap[son1];
														heap[son1]:=step;
														exit;
													 end;
	if (d[heap[son1]]<d[heap[son2]]) then
										if d[heap[a]]>d[heap[son1]] then begin
																			where[heap[a]]:=son1;
																			where[heap[son1]]:=a;
																			step:=heap[a];
																			heap[a]:=heap[son1];
																			heap[son1]:=step;
																			down(son1);
																		 end
																	else nothing:=1
									 else
										if d[heap[a]]>d[heap[son2]] then begin
																			where[heap[a]]:=son2;
																			where[heap[son2]]:=a;
																			step:=heap[a];
																			heap[a]:=heap[son2];
																			heap[son2]:=step;
																			down(son2);
																		 end
end;
procedure change(a:longint);
begin
	inc(top);
	where[a]:=top;
	heap[top]:=a;
	sert(top);
end;
procedure Dijkstra;
begin
	for j:=1 to (n-1)*(m-1)*2+1 do
	begin
		x:=heap[1];
		heap[1]:=heap[top];
		where[heap[top]]:=1;
		dec(top);
		down(1);
		i:=headlist[x];
		while i<>-1 do
		begin
			if d[x]+weight[i]<d[t[i]] then if d[t[i]]=maxlongint then begin
 																	d[t[i]]:=d[x]+weight[i];
																		change(t[i]);
																	  end
															     else begin
																		d[t[i]]:=d[x]+weight[i];
																		sert(where[t[i]]);
																	  end;
			i:=next[i];
		end;
	end;
end;
procedure First;
begin
	d[0]:=0;
	for i:=1 to 2*(n-1)*(m-1)+1 do d[i]:=maxlongint;
	i:=headlist[0];
	while (i<>-1) do
	begin
		if t[i]=(n-2)*2*(m-1)+1 then begin
										if tot=1 then if weight[i]<d[t[i]] then begin
																					d[t[i]]:=weight[i];
																					sert(where[t[i]]);
																				end;
										inc(tot);
										if tot=2 then begin i:=next[i]; continue; end;
									end;
		d[t[i]]:=weight[i];
		change(t[i]);
        i:=next[i];
	end;
end;
procedure main;
begin
	init;
	First;
	Dijkstra;
	writeln(d[(n-1)*2*(m-1)+1]);
end;
begin
	main;
end.


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值