首页 > 其他分享 > P6419 [COCI2014-2015#1] Kamp

P6419 [COCI2014-2015#1] Kamp

时间:2023-10-24 19:23:10浏览次数:37  
标签:路径 子树内 COCI2014 up Kamp ans 2015 节点 dis


 

 

题目描述

一颗树 nn 个点,n−1n−1 条边,经过每条边都要花费一定的时间,任意两个点都是联通的。

有 KK 个人(分布在 KK 个不同的点)要集中到一个点举行聚会。

聚会结束后需要一辆车从举行聚会的这点出发,把这 KK 个人分别送回去。

请你回答,对于 i=1∼ni=1∼n ,如果在第 ii 个点举行聚会,司机最少需要多少时间把 KK 个人都送回家。

输入格式

第一行两个整数 n,Kn,K 。

接下来 n−1n−1 行,每行三个数 x,y,zx,y,z 表示 xx 到 yy 之间有一条需要花费 zz 时间的边。

接下来 KK 行,每行一个数,表示 KK 个人的分布。

输出格式

输出 nn 个数。

第 ii 行的数表示:如果在第 ii 个点举行聚会,司机需要的最少时间。

输入输出样例

输入 #1
7 2
1 2 4
1 3 1
2 5 1
2 4 2
4 7 3
4 6 2
3
7
输出 #1
11
15
10
13
16
15
10
输入 #2
5 2
2 5 1
2 4 1
1 2 2
1 3 2
4
5
输出 #2
5
3
7
2
2

 感觉这题没有紫题的难度....

换根dp的特征感觉还是非常明显的,就是答案“可被移动“
具体点就是可以在logn或者是n的时间内通过计算来把一个节点的答案转化得到另一个节点的答案
这题就很明显,虽然要分类讨论,还有其他的挺多的限制和要求...主要是分类讨论很烦人。。

我简单说一下思路吧

第一遍dfs直接把从每个点出发经过它子树内所有终点并返回的路劲长度算出来
这个是最基础的,还有一些其他要算的我后面会说

然后第二遍dfs就需要算出来全局的答案了,就是从一个点出发,经过全图所有点并返回的路径长

如果有仔细一点,推过样例的同学就会发现,答案要求的不是这个,而是不返回的最短路径
就是车车把最后一个人送回家后,离开停下,到此为止它开的最短路径

这个路径和我们统计的路径有什么区别呢?
很明显,有一个容易证明的贪心,这个最短路径,就是我们上面算出来的路径减去这个点到离这个点最远的点路径长
(因为不用返回嘛)

那么,很明显,如果我们只是统计一个子树的根节点到这个子树内的终点的最短路径,这个在第一个dfs内就可以直接完成
问题就在于,怎么计算整棵树范围的,也就是全图的答案。

假如这个子树的根节点就是这棵树的根,那很明显这个最短路径就是我们要的最短路径
那我们在第一遍dfs的时候所用的根就是我们第二遍换根dp的起点

那我们现在要考虑的就是,已知一个节点作为跟的时候的答案,怎么把这个答案转移到其子节点上?也就是如何换根
要分类讨论了

首先我们以1号节点为根

f[u] 从点u出发把所有在u的子树里的人送回家并返回u的距离

ans[u]从点u出发把所有人出发并返回u的距离

dis[u] 从u出发,在u的子树内,距离u最远的那个人的家到u的距离

sdis[u] 从u出发,在u的子树内,距离u次远的那个人家到u的距离并且这个人的家和dis[u]不在同一个子树内(这个东西的作用后面会说到)

up[u] 不在u的子树内,距离u最远的那个人的家到u的距离

siz[u] u及u的子树内有多少个人的家

f[u],siz[u],dis[u],sdis[u]在第一遍dfs内就可以求出来

关键的是up[u]和ans[u]的计算

设fa为u的父亲节点,w为u和fa之间的路径长度

ans[u]的计算规则

1.当siz[u]==0时,ans[u]=ans[fa]+w*2
2.当siz[u]==k(就是所有的重点都在这个子树内)时,ans[u]=f[u]
3.其他的情况,ans[u]=fa[u]

up[u]的计算规则就更复杂一些

1.当siz[u]==0,up[u]=up[fa]+w

2.当siz[u]==k,up[u]=0

3.其他情况

  有两种,一种是最长的就是up[fa]+w
  一种是最长的要经过它的兄弟节点
  第二种还有两种情况。。
  如果dis[u]>up[u](就是上面说的第二种情况的一种)但是这个dis[u]实际上是经过了u的,那肯定是不能要的
  但是它的兄弟节点的可能却没有被考虑到
  所以对每一个节点就要记录一个最长路,和一个不和最长路相交的次长路,也就是dis[u]和sdis[u]

那这样最后的答案就是ans[i]-max(up[i],dis[i])

有一说一真的没有紫题难度。。不知道为什么是紫题

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
inline ll read() {
    char c=getchar();ll a=0,b=1;
    for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
    for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;return a*b;
}
struct edge
{
    ll next,to,v;
}e[1000501];
ll head[1000501],tot,n,k,vis[1000501],f[1000001],ans[1000001],sum[1000001];
ll len[1000501],slen[1000501],dis[1000501],sdis[1000501];//·Ö±ðÊÇÀëi×îÔ¶µÄµãºÍ´ÎÔ¶µÄµãµÄ¾àÀ룬ÒÔ¼°ÕâÌõÁ´µÄµÚÒ»¸öµãÔÚÄÄÀï 
ll up[1000501];
inline void add(ll i,ll j,ll k)
{
    e[++tot].next=head[i];
    e[tot].to=j;
    e[tot].v=k;
    head[i]=tot;
}
void dfsfirst(ll x,ll fa)
{
    if(vis[x])sum[x]++;
    for(ll i=head[x];i!=0;i=e[i].next)
    {
        ll u=e[i].to;
        if(u==fa)continue;
        dfsfirst(u,x);
        if(sum[u])
        {
            ll now=len[u]+e[i].v;
            f[x]+=f[u]+e[i].v*2;
            if(len[x]<now)
                sdis[x]=dis[x],
                dis[x]=u,
                slen[x]=len[x],
                len[x]=now;
            else
            if(slen[x]<now)
                sdis[x]=u,
                slen[x]=now;
        }
        sum[x]+=sum[u];
    }
}
void dfsecond(ll x,ll fa)//¸üÐÂÈ«¾Ö´ð°¸ 
{
    for(ll i=head[x];i!=0;i=e[i].next)
    {
        ll u=e[i].to;
        if(u==fa)continue;
        if(sum[u]==0)
        {
            ans[u]=ans[x]+e[i].v*2;
            up[u]=max(up[x],len[x])+e[i].v;
        }
        else
        if(sum[u]==k)
        {
            ans[u]=f[u];
            up[u]=0;
        }
        else
        {
            ans[u]=ans[x];
            if(dis[x]==u)up[u]=max(up[x],slen[x])+e[i].v;//Ϊʲô´Î³¤¾Í²»»á¾­¹ý,ÒòΪÎÒÉÏÃæÿÌõ¶¼Ö»È¡ÁËÒ»Ìõ×î´óÖµ°¡¡£¡£¡£ 
            else up[u]=max(up[x],len[x])+e[i].v;
        }
        dfsecond(u,x);
    }
}
int main()
{
    n=read();k=read();
    for(ll i=1;i<n;i++)
    {
        ll a=read(),b=read(),c=read();
        add(a,b,c);add(b,a,c);
    }
    for(ll i=1;i<=k;i++)
    {
        vis[read()]=1;
    }
    dfsfirst(1,0);
    ans[1]=f[1];up[1]=0;
    dfsecond(1,0);
    for(ll i=1;i<=n;i++)
    {
        cout<<ans[i]-max(up[i],len[i])<<endl;
    }
    return 0;
}

 

 

 

标签:路径,子树内,COCI2014,up,Kamp,ans,2015,节点,dis
From: https://www.cnblogs.com/HLZZPawa/p/17785505.html

相关文章

  • P2679 [NOIP2015 提高组] 子串 题解
    #include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintMOD=1000000007;intn,m,k,dp[205][205][2];charA[1005],B[205];signedmain(){cin.tie(0)->sync_with_stdio(0);cin>>n>>m>>k;cin......
  • P4253 [SCOI2015] 小凸玩密室
    P4253bzoj#4446非常好的一道树形dp题起初我看错题了QwQ,以为第一个选的必须为根首先我们发现假设我们选的第一个灯泡为\(u\),他的行走过程是:\(u\rightarrowu\)子树\(\rightarrowfa_u\rightarrowu\)兄弟子树\(\rightarrowfa_{fa_u}\rightarrow\dots\)因此我......
  • P4155 [SCOI2015] 国旗计划
    按套路破环成链,要注意右端点小于左端点的区间跨越了\(N\to1\)。假设钦定了士兵\(i\),接下来肯定贪心地选择左端点小于等于当前右端点的右端点最大的下一个区间。因为区间不存在包含关系,按右端点从小到大排序后形式化地讲就是找到最大的\(j\)使得\(C_j\leqD_i\)。直接做是......
  • [ZJOI2015] 地震后的幻想乡积分题解
    题意:给定一个无向图,边权为\([0,1]\)之间的随机变量。求图最小生成树最大边权的期望。\(n\le10\)。Soluion:Meatherm口诏:我都不知道这个东西怎么想出来的针对这道题,好像正常的方法是转计数然后斯特林反演+dp。但是如果想到概率理论,你就已经赢了很遗憾,我没想出来设最大边......
  • ZJOI2015 地震后的幻想乡
    「ZJOI2015」地震后的幻想乡前言:想了很久,最后只能失败告终。基本分析到了一半,只是没有将其转化为古典概型后考虑求解方案数。说实话有点可惜……题意:给定一张\(n\)个点\(m\)条边的无向连通图,每条边的边权是\([0,1]\)之间的随机实数,求其最小生成树上最大边权的期望值......
  • VS2015重构代码结构时出现:【/langversion 的选项“7.3”无效;必须是 ISO-1、ISO-2、3
    重构代码结构时出现:【/langversion的选项“7.3”无效;必须是ISO-1、ISO-2、3或Default在XXXX类库】......
  • [COCI2015-2016#4] ENDOR 题解
    [COCI2015-2016#4]ENDOR题解首先要发现一个很重要的性质,那就是两只变色龙碰撞后回头,等效于两只变色龙继续往前走,其中向右走的颜色不变,而向左走的要改变颜色。那这样就有一种\(O(n^2)\)的做法:对于向右的变色龙,直接贡献答案;对于向左的变色龙,我们按照碰到的先后顺序枚举它前面......
  • P3177 [HAOI2015] 树上染色
    P3177[HAOI2015]树上染色[P3177HAOI2015]树上染色-洛谷|计算机科学教育新生态(luogu.com.cn)目录P3177[HAOI2015]树上染色题目大意思路code题目大意有一棵\(n\)个点的树,你可以在上面把\(k\)个点染成黑色,收益为黑点两两之间的距离和加上白点两两之间的距离和求......
  • P3586 [POI2015] LOG
    原题先写我复杂度错误的一个思路:首先每次选最小的\(c\)个做显然是优秀的,贪心性质显然,打表找一下答案?12302-13-1+11003-24-2+1+2-120004-3+15-3+2+3-23......
  • [ICPC2015WF] Tours
    题目描述TheArcaCaraniaMountainnationalparkisopeningupfortouristtraffic.Thenationalparkhasanumberofsitesworthseeingandroadsthatconnectpairsofsites.Theparkcommissionershaveputtogetherasetofroundtoursintheparkinwhich......