「CodeForces 191C」Fools and Roads 发表于 2018-08-07 | 字数统计: 561 | 阅读时长 ≈ 3 给一棵有根树和一些路线,路线上的边权都+1,求所有边的权值 链接CodeForces 191C 题解这个题目的输出是每一条边所经过的次数,所以想到树上边差分。在差分之后确实是晕了,没有想到好的方法,但是突然想到了DFS求树上前缀和,对于每一条边,只要计算深度小的前缀和-深度大的前缀和即得答案。 代码123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123#include<bits/stdc++.h>using namespace std;typedef int ll;struct edge{ ll to,prev; };ll nc,ec,query,root,from,to;ll depth[500010],anc[500010][31],last[500010],diff[500010],prefix[500010],LCA,maxn;ll From[500010],To[500010];edge ed[500010*2];inline void addEdge(ll from,ll to){ ed[++ec].prev=last[from]; ed[ec].to=to; last[from]=ec;}inline void dfs(ll node){ ll son; for(register int i=last[node];i!=0;i=ed[i].prev) { son=ed[i].to; if(!depth[son]) { depth[son]=depth[node]+1; anc[son][0]=node; dfs(son); } }}inline void LCASetup(){ depth[1]=1; anc[1][0]=0; dfs(1); for(register int i=1;i<=21;i++) { for(register int j=1;j<=nc;j++) { anc[j][i]=anc[anc[j][i-1]][i-1]; } }}inline ll lca(ll x,ll y){ if(depth[x]>depth[y]) { swap(x,y); } for(register int i=21;i>=0;i--) { if(depth[anc[y][i]]>=depth[x]) { y=anc[y][i]; } } if(x==y) { return x; } for(register int i=21;i>=0;i--) { if(anc[x][i]!=anc[y][i]) { x=anc[x][i]; y=anc[y][i]; } } return anc[x][0];}inline void ddfs(ll node){ for(register int i=last[node];i;i=ed[i].prev) { if(ed[i].to==anc[node][0]) { continue; } ddfs(ed[i].to); diff[node]+=diff[ed[i].to]; }}inline void dffs(ll node,ll val){ prefix[node]=diff[node]+val; for(register int i=last[node];i;i=ed[i].prev) { if(ed[i].to==anc[node][0]) { continue; } dffs(ed[i].to,prefix[node]); }}int main(){ scanf("%d",&nc); for(register int i=0;i<nc-1;i++) { scanf("%d%d",&from,&to); From[i]=from,To[i]=to; addEdge(from,to); addEdge(to,from); } LCASetup(); scanf("%d",&query); for(register int i=0;i<query;i++) { scanf("%d%d",&from,&to); LCA=lca(from,to); diff[from]++,diff[to]++,diff[LCA]-=2; } ddfs(1); dffs(1,0); for(register int i=0;i<nc-1;i++) { if(depth[From[i]]<depth[To[i]]) { swap(From[i],To[i]); } printf("%d ",prefix[From[i]]-prefix[To[i]]); }} 本文作者: Karry5307 本文链接: http://karry5307.github.io/2018/08/07/「CodeForces-191C」Fools-and-Roads/ 版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明出处!