B1060 [ZJOI2007]时态同步 dfs
Posted dukelv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了B1060 [ZJOI2007]时态同步 dfs相关的知识,希望对你有一定的参考价值。
两遍dfs,第一遍有点像找重链,第二遍维护答案,每个点维护一个当前深度,然后就没啥了。
ps:memset(lst,-1,sizeof(lst));这一句多余的话让我debug半天。。。
题干:
Description 小Q在电子工艺实习课上学习焊接电路板。一块电路板由若干个元件组成,我们不妨称之为节点,并将其用数 字1,2,3….进行标号。电路板的各个节点由若干不相交的导线相连接,且对于电路板的任何两个节点,都存在且仅 存在一条通路(通路指连接两个元件的导线序列)。在电路板上存在一个特殊的元件称为“激发器”。当激发器工 作后,产生一个激励电流,通过导线传向每一个它所连接的节点。而中间节点接收到激励电流后,得到信息,并将 该激励电流传向与它连接并且尚未接收到激励电流的节点。最终,激烈电流将到达一些“终止节点”——接收激励 电流之后不再转发的节点。激励电流在导线上的传播是需要花费时间的,对于每条边e,激励电流通过它需要的时 间为te,而节点接收到激励电流后的转发可以认为是在瞬间完成的。现在这块电路板要求每一个“终止节点”同时 得到激励电路——即保持时态同步。由于当前的构造并不符合时态同步的要求,故需要通过改变连接线的构造。目 前小Q有一个道具,使用一次该道具,可以使得激励电流通过某条连接导线的时间增加一个单位。请问小Q最少使用 多少次道具才可使得所有的“终止节点”时态同步? Input 第一行包含一个正整数N,表示电路板中节点的个数。第二行包含一个整数S,为该电路板的激发器的编号。接 下来N-1行,每行三个整数a , b , t。表示该条导线连接节点a与节点b,且激励电流通过这条导线需要t个单位时 间 Output 仅包含一个整数V,为小Q最少使用的道具次数 Sample Input 3 1 1 2 1 1 3 3 Sample Output 2 HINT N ≤ 500000,te ≤ 1000000 Source
代码:
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(int i = a;i <= n;i++) #define lv(i,a,n) for(int i = a;i >= n;i--) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < ‘0‘ || c > ‘9‘) if(c == ‘-‘) op = 1; x = c - ‘0‘; while(c = getchar(), c >= ‘0‘ && c <= ‘9‘) x = x * 10 + c - ‘0‘; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar(‘-‘), x = -x; if(x >= 10) write(x / 10); putchar(‘0‘ + x % 10); } struct node { int r,nxt; ll w; }a[1000010]; int len = 0,lst[1000010],n,s; ll dep[1000010]; void add(int x,int y,ll w) { a[++len].r = y; a[len].w = w; a[len].nxt = lst[x]; lst[x] = len; } ll sum = 0; ll dfs(int x,int f) { for(int k = lst[x];k;k = a[k].nxt) { int y = a[k].r; if(y == f) continue; dfs(y,x); dep[x] = max(dep[x],dep[y] + a[k].w); } for(int k = lst[x];k;k = a[k].nxt) { int y = a[k].r; if(y == f) continue; sum += dep[x] - dep[y] - a[k].w; } return dep[x]; } int main() { read(n);read(s); // memset(lst,-1,sizeof(lst)); 就是这一句!!! duke(i,1,n - 1) { int x,y; ll z; read(x);read(y);read(z); add(x,y,z); add(y,x,z); } dfs(s,s); printf("%lld ",sum); return 0; }
以上是关于B1060 [ZJOI2007]时态同步 dfs的主要内容,如果未能解决你的问题,请参考以下文章
[树形DP]Luogu P1131 [ZJOI2007]时态同步