zoukankan      html  css  js  c++  java
  • [CF1004E] Sonya and Ice-cream

    问题描述

    Sonya likes ice cream very much. She eats it even during programming competitions. That is why the girl decided that she wants to open her own ice cream shops.

    Sonya lives in a city with n junctions and n−1 streets between them. All streets are two-way and connect two junctions. It is possible to travel from any junction to any other using one or more streets. City Hall allows opening shops only on junctions. The girl cannot open shops in the middle of streets.

    Sonya has exactly k friends whom she can trust. If she opens a shop, one of her friends has to work there and not to allow anybody to eat an ice cream not paying for it. Since Sonya does not want to skip an important competition, she will not work in shops personally.

    Sonya wants all her ice cream shops to form a simple path of the length r (1≤r≤k), i.e. to be located in different junctions f1,f2,…,fr and there is street between fi and fi+1 for each ii from 1 to r−1.

    The girl takes care of potential buyers, so she also wants to minimize the maximum distance between the junctions to the nearest ice cream shop. The distance between two junctions aa and bb is equal to the sum of all the street lengths that you need to pass to get from the junction aa to the junction b. So Sonya wants to minimize

    maxamin1≤i≤rda,fi

    where a takes a value of all possible n junctions, fi — the junction where the ii-th Sonya's shop is located, and dx,y — the distance between the junctions x and y.

    Sonya is not sure that she can find the optimal shops locations, that is why she is asking you to help her to open not more than k shops that will form a simple path and the maximum distance between any junction and the nearest shop would be minimal.

    输入格式

    The first line contains two integers n and k (1≤k≤n≤105) — the number of junctions and friends respectively.

    Each of the next n−1 lines contains three integers ui, vi, and di (1≤ui,vi≤n, vi≠ui, 1≤d≤104) — junctions that are connected by a street and the length of this street. It is guaranteed that each pair of junctions is connected by at most one street. It is guaranteed that you can get from any junctions to any other.

    输出格式

    Print one number — the minimal possible maximum distance that you need to pass to get from any junction to the nearest ice cream shop. Sonya's shops must form a simple path and the number of shops must be at most k.

    样例输入

    6 2
    1 2 3
    2 3 4
    4 5 2
    4 6 3
    2 4 6

    样例输出

    4

    解析

    首先,满足要求的一条链一定在树的直径上。那么,设len为直径的长度,(dis1[i])表示直径上的点i到直径左个端点的距离,(dis2[i])表示直径上点i不经过直径上的点能到达的最远的点。将直径视为一个序列,并重新由左端点从1开始标号,那么,设直径有m个点,答案即为

    [Max_{i=1}^{m-k+1}(dis1[i],len-dis1[i+k-1],max(dis2[i],dis2[i+1],...,dis2[i+k-1])) ]

    前面两个值可以直接计算得到,后面的那个max可以转化为滑动窗口问题,用单调队列解决即可。

    代码

    #include <iostream>
    #include <cstdio>
    #define N 100002
    using namespace std;
    int head[N],ver[N*2],nxt[N*2],edge[N*2],l;
    int n,k,i,j,d[N],dis[N],d1[N],d2[N],fa[N],len,cnt,a,b,tmp,maxx,q[N],h,t;
    bool vis[N];
    int read()
    {
    	char c=getchar();
    	int w=0;
    	while(c<'0'||c>'9') c=getchar();
    	while(c<='9'&&c>='0'){
    		w=w*10+c-'0';
    		c=getchar();
    	}
    	return w;
    }
    void insert(int x,int y,int z)
    {
    	l++;
    	ver[l]=y;
    	edge[l]=z;
    	nxt[l]=head[x];
    	head[x]=l;
    }
    void dfs(int x,int pre)
    {
    	fa[x]=pre;
    	for(int i=head[x];i;i=nxt[i]){
    		int y=ver[i];
    		if(y!=pre&&!vis[y]){
    			dis[y]=dis[x]+edge[i];
    			if(dis[y]>maxx) maxx=dis[y],tmp=y;
    			dfs(y,x);
    		}
    	}
    }
    int main()
    {
    	n=read();k=read();
    	for(i=1;i<n;i++){
    		int u=read(),v=read(),w=read();
    		insert(u,v,w);
    		insert(v,u,w);
    	}
    	dfs(1,0);
    	maxx=0;dis[tmp]=0;
    	dfs(tmp,0);
    	len=maxx;
    	while(tmp!=0){
    		cnt++;
    		d[cnt]=tmp;
    		d1[cnt]=len-dis[tmp];
    		vis[tmp]=1;
    		tmp=fa[tmp];
    	}
    	for(i=1;i<=cnt;i++){
    		maxx=0;dis[d[i]]=0;
    		dfs(d[i],0);
    		d2[i]=maxx;
    	}
    	int ans=1<<30;
    	for(i=1,j=1;i<=cnt;i++){
    		while(h<=t&&q[h]<i) h++;
    		while(j<=min(i+k-1,cnt)){
    			while(h<=t&&d2[q[t]]<=d2[j]) t--;
    			q[++t]=j;
    			j++;
    		}
    		ans=min(ans,max(max(d1[i],len-d1[min(i+k-1,cnt)]),d2[q[h]]));
    	}
    	if(ans==1<<30) puts("0");
    	else printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    资源利用率提高67%,腾讯实时风控平台云原生容器化之路
    热门分享预告|腾讯大规模云原生平台稳定性实践
    Fluid + GooseFS 助力云原生数据编排与加速快速落地
    基于 Clusternet 与 OCM 打造新一代开放的多集群管理平台
    案例 | 沃尔玛 x 腾讯云 Serverless 应用实践,全力保障消费者购物体验
    SuperEdge 高可用云边隧道有哪些特点?
    kubernetes 降本增效标准指南|ProphetPilot:容器智能成本管理引擎
    公有云上构建云原生 AI 平台的探索与实践
    如何削减 50% 机器预算?“人机对抗”探索云端之路
    SuperEdge 易学易用系列-SuperEdge 简介
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11725870.html
Copyright © 2011-2022 走看看