[ZJOI2007] 时态同步
一道可以说是弱智的构造题,这和DP有半毛钱关系吗,然而并没有。
很明显,假如你要给u到v的边(u为父亲)加上一个边权,相当于就默认了v子树内所有叶子到v的距离相同,因为所有比v浅的边的边权的改变都不会改变子树内的距离大小关系,毕竟同加同减。然后明白这一点,搜索加贪心即可。
我竟然只用了十分钟敲代码。感动至极。
#include<cstdio>
#define zczc
#define int long long
const int N=500010;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int max(int s1,int s2){
return s1<s2?s2:s1;
}
int m,s;
struct edge{
int t,v,next;
}e[N<<1];
int head[N],esum;
inline void add(int fr,int to,int val){
e[++esum]=(edge){to,val,head[fr]};head[fr]=esum;
}
int ans,d[N];
void dfs(int wh,int fa){
for(int i=head[wh],th;i;i=e[i].next){
if((th=e[i].t)==fa)continue;
dfs(th,wh);d[wh]=max(d[wh],d[th]+=e[i].v);
}
for(int i=head[wh],th;i;i=e[i].next){
if((th=e[i].t)==fa)continue;
ans+=d[wh]-d[th];
}
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);read(s);int s1,s2,s3;
for(int i=1;i<m;i++){
read(s1);read(s2);read(s3);
add(s1,s2,s3);add(s2,s1,s3);
}
dfs(s,0);
printf("%lld",ans);
return 0;
}
一如既往,万事胜意