消防(mindist)

消防(mindist)
【问题描述】
某个国家有n 个城市,这n 个城市中任意两个都连通且有唯一一条路径,每
条连通两个城市的道路的长度为zi(zi<=1000)。
这个国家的人对火焰有超越宇宙的热情,所以这个国家最兴旺的行业是消防
业。由于政府对国民的热情忍无可忍(大量的消防经费开销)可是却又无可奈何
(总统竞选的国民支持率),所以只能想尽方法提高消防能力。
现在这个国家的经费足以在一条边长度和不超过s 的路径(两端都是城市)
上建立消防枢纽,为了尽量提高枢纽的利用率,要求其他所有城市到这条路径的
距离的最大值最小。
你受命监管这个项目,你当然需要知道应该把枢纽建立在什么位置上。
【输入格式】
输入包含n 行:
第1 行,两个正整数n 和s,中间用一个空格隔开。其中n 为城市的个数,
s 为路径长度的上界。设结点编号以此为1,2,……,n。
从第2 行到第n 行,每行给出3 个用空格隔开的正整数,依次表示每一条边的
两个端点编号和长度。例如,“2 4 7”表示连接结点2 与4 的边的长度为7。
【输出格式】
输出包含一个非负整数,即所有城市到选择的路径的最大值,当然这个最大
值必须是所有方案中最小的。

【样例输入1】

5 2
1 2 5
2 3 2
2 4 4
2 5 3
【样例输出1】
5
【样例输入2】
8 6
1 3 2

2 3 2
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3
【样例输出2】
5
【数据规模和约定】
对于20%的数据,n<=300。
对于50%的数据,n<=3000。
对于100%的数据,n<=300000,边长小等于1000。


可以证明,建立枢纽的路必然在树的直径(即树的最长链)上

这个问题明显具有单调性,如果3可以,那4也可以

所以可以二分答案,问题就变为已知一个答案,如何验证是否可行

首先预处理一下直径上的点的不在直径上的最长链,其中最长的即为答案下界

然后贪心处理即可,从链的底部出发向上,在不超过答案的情况下就不把边删除,之后能删除多少边就删除多少边,删除完判断合法不合法即可


program mindist;
var
  mid,l,r,bot,top,max,tot,n,s,i,j,k,u,v,c:longint;
  val,oth,father,dis,root:array [0..300001] of longint;
  next,cost,point:array [0..600001] of longint;
  line:array [0..300001] of boolean;

procedure connect (u,v,c:longint);inline;
begin
  inc(tot);
  point[tot]:=v;
  cost[tot]:=c;
  next[tot]:=root[u];
  root[u]:=tot;
end;

procedure search (now:longint);
var
  i:longint;
begin
  if dis[now]>dis[max] then max:=now;
  i:=root[now];
  while i<>0 do
    begin
      if point[i]<>father[now] then
        begin
          dis[point[i]]:=dis[now]+cost[i];
          father[point[i]]:=now;
          val[point[i]]:=cost[i];
          search(point[i]);
        end;
      i:=next[i];
    end;
end;

procedure dfs (now:longint);
var
  i:longint;
begin
  i:=root[now];
  while i<>0 do
    begin
      if point[i]<>father[now] then
        begin
          dfs(point[i]);
          if not line[point[i]] then
            if oth[point[i]]+cost[i]>oth[now] then
              oth[now]:=oth[point[i]]+cost[i];
        end;
      i:=next[i];
    end;
  if oth[now]>max then max:=oth[now];
end;

function ok (ans:longint):boolean;
var
  i,k,now:longint;
begin
  i:=bot;
  while (i<>top)and(dis[bot]-dis[father[i]]<=ans) do i:=father[i];
  now:=0;
  while i<>top do
    begin
      if now+val[i]>s then break;
      now:=now+val[i];
      i:=father[i];
    end;
  if dis[i]>ans then exit(false)
                else exit(true);
end;

begin
  assign(input,'mindist.in');
  reset(input);
  assign(output,'mindist.out');
  rewrite(output);
  read(n,s);
  for i:=1 to n-1 do
    begin
      read(u,v,c);
      connect(u,v,c);
      connect(v,u,c);
    end;
  fillchar(father,sizeof(father),0);
  fillchar(dis,sizeof(dis),0);
  max:=1;
  search(1);
  top:=max;
  fillchar(father,sizeof(father),0);
  fillchar(dis,sizeof(dis),0);
  search(top);
  bot:=max;
  fillchar(line,sizeof(line),false);
  i:=bot;
  repeat
    line[i]:=true;
    i:=father[i];
  until i=0;
  max:=0;
  dfs(top);
  l:=max;
  r:=300000;
  while l<>r do
    begin
      mid:=(l+r) div 2;
      if ok(mid) then r:=mid
                 else l:=mid+1;
    end;
  writeln(l);
  close(input);
  close(output);
end.




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这行代码是对聚类过程中的每个样本点计算其属于哪个簇,即将每个样本点分配到其最近的簇中。其中,clusterAssment[i,:] 表示第 i 个样本点的簇分配结果,包含两个值:簇索引和样本点到簇中心的距离,minIndex 表示样本点的最近簇的索引,minDist 表示样本点到最近簇中心的距离。所以,这行代码的作用就是将第 i 个样本点分配给距离其最近的簇,并将该分配结果存储在 clusterAssment 中。 ### 回答2: 这行代码是用来解释将变量`minIndex`和`minDist`的值赋给数组`clusterAssment`中的第`i`行。 其中`clusterAssment`是一个二维数组,第`i`行对应着数据集中的第`i`个样本的聚类结果。 `minIndex`表示当前样本点与所有聚类中心之间距离最近的聚类中心的索引。 `minDist`表示当前样本点与最近聚类中心的距离。 通过代码`clusterAssment[i, :] = minIndex, minDist`,将`minIndex`和`minDist`的值赋给了`clusterAssment`数组中的第`i`行。这意味着将聚类结果的索引和距离保存在了数组中,以供后续使用和分析。 这行代码的作用是更新聚类结果矩阵,使得矩阵中每一行对应的样本点的聚类结果与距离被正确记录。这可以用于后续聚类结果的可视化、评估或其他分析。 ### 回答3: 代码clusterAssment[i, :] = minIndex, minDist的解释如下: 这行代码的作用是将变量minIndex和minDist赋值给数组clusterAssment的第i行。 其中,clusterAssment是一个二维数组,每一行表示一个数据点的聚类分配和到聚类中心的距离。而minIndex是当前数据点所属的最近的聚类中心的索引,minDist是当前数据点到最近的聚类中心的距离。 通过将minIndex和minDist赋值给clusterAssment的第i行,我们实际上将当前数据点的聚类分配和到聚类中心的距离记录了下来,以便后续的分析和使用。这样,我们可以方便地获取每个数据点的聚类分配和距离信息,并对其进行进一步的处理和分析。 这行代码使用了“=”运算符,表示将minIndex和minDist的值分别赋给clusterAssment第i行的两个元素,minIndex赋给第一个元素,minDist赋给第二个元素。同时,我们利用了冒号“:”,表示访问数组的整行,即访问clusterAssment的第i行。 总而言之,代码clusterAssment[i, :] = minIndex, minDist的目的是将当前数据点的聚类分配和到聚类中心的距离记录到clusterAssment的第i行,以备后续的使用和分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值