POJ1849 Two——贪心

类似于树形动态规划的贪心。题目大意:

这个城市由节点和连接节点的街道组成,街道是双向的。此刻大雪覆盖了这个城市,市长确定了一些街道要将它们清扫干净,这些街道的确定保证所有节点可以通过它们连通而且街道数目尽可能小。有两台相同的扫雪机S和M,它们的起点在同一个节点上。

所有被确定的街道必须至少被一台扫雪机经过,才能完成清扫任务,完成任务后S和M可以在原地停下,不必集合到某一点。扫雪机的行进是需要耗费油量的(即使扫雪机行驶的是已被扫净的街道),因此扫雪机行进的总距离越小越好,你需要计算两台扫雪机完成任务的最小总行进距离。

 

{以上感谢铎铎大牛提供的翻译}

 

解法:

首先从根节点出发找到一条最长的链,然后将这条链上路径的长度len全部设为-len

再从根节点出发找到一条最长的连

树中每条边的长度之和*2-两条链的长度之和就是答案。

 

贪心证明:显然,画画图就明白了

 

CODE

Program Two;//By_thispoet
Const
	maxn=300000;
Var
	p,q,i,j,k,m,n,s,tmp,ans        :Longint;
	pre,other,last,len	           :Array[0..maxn]of Longint;
	size,father,deal,res,kset       :Array[0..maxn]of Longint;
	flag,v                  :Array[0..maxn]of Boolean;

Procedure Dfs(i:Longint);
var j,k:Longint;
begin

	j:=last[i];

	while j<>0 do
		begin
			k:=other[j];

			if k<>father[i] then
				begin
					father[k]:=i;
					if flag[k] then size[k]:=size[i]+len[j] else
						size[k]:=size[i]-len[j];
					Dfs(k);
				end;

			j:=pre[j];
		end;

end;


BEGIN

	readln(n,s);
	for i:=1 to n-1 do
		begin
			readln(p,q,m);
			inc(k);pre[k]:=last[p];last[p]:=k;other[k]:=q;len[k]:=m;
			inc(k);pre[k]:=last[q];last[q]:=k;other[k]:=p;len[k]:=m;
			inc(ans,m*2);
		end;

	fillchar(flag,sizeof(flag),1);
	size[s]:=0;
	Dfs(s);

	tmp:=1;
	for i:=2 to n do
		if size[i]>size[tmp] then tmp:=i;
	p:=size[tmp];
	while tmp<>s do
		begin
			j:=last[tmp];
			while other[j]<>father[tmp] do j:=pre[j];
			flag[tmp]:=false;
			tmp:=father[tmp];
		end;

	Dfs(s);

	tmp:=1;
	for i:=2 to n do
		if size[i]>size[tmp] then tmp:=i;
	inc(p,size[tmp]);

	dec(ans,p);

	writeln(ans);

END.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值