【P2052】道路修建(树形+搜索)
这个题看上去高大上,实际上就是一个大水题。怎么说呢,这个题思路可能比较难搞,代码实现难度几乎为0.
首先我们可以发现这是一棵树,然后问其中任意一条边左右两边的点的数量之差的绝对值,实际上,无论两边的点是多少,我们都可以用abs(n-2*x)(x代表这条边的一个端点的儿子的个数)算出来,这样我们就减少了一大部分我们的工作,我们只需要在dfs遍历树的时候在返回的时候进行一个子节点的增加和和的计算,这个题就可以轻松得出结果。讨论里说要开ll,所以蒟蒻一遍A了。。
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define re register using namespace std; struct po { int next; int to; int dis; }; po edge[1000001]; long long head[1000001],b[1000001],temp[1000001],tot[1000001],ans; long long dis[1000001]; int T,s,t,n,m,x,w,a,l,num,flag,d; inline void add_edge(int from,int to,int dis) { edge[++num].next=head[from]; edge[num].to=to; edge[num].dis=dis; head[from]=num; } inline void dfs(int to,int fa) { tot[to]=1; for(re int i=head[to];i;i=edge[i].next) { if(edge[i].to==fa) continue; dfs(edge[i].to,to); tot[to]+=tot[edge[i].to]; ans+=edge[i].dis*abs(n-2*tot[edge[i].to]); } } int main() { cin>>n; for(re int i=1;i<=n-1;i++) { cin>>s>>t>>d; add_edge(s,t,d); add_edge(t,s,d); } dfs(1,0); cout<<ans; }
对于作者转载文章,欢迎继续转载。
对于作者原创文章,请注明出处之后转载。