题目大意:

给定所有点的权值都为0,给定一棵树以后,每次询问都要求给定两点 x , y 和一个权值w,要求x,y路径上所有点权值加上w,最后求出每一个节点的值

这里因为查询和点都特别多,所以希望能最后一次性更新节点的值

我们可以这么考虑,每次询问中找到x,y的最近公共祖先,那么我们将val[x] +=w , val[y]+=w , val[lca]-=w;

最后做dfs的时候,不断自底向上更新val值,让父亲加上所有儿子的val值,那么lca减掉了一个w,最后2端会加上两个w,最后还是相当于加了一个w

但是因为lca加了一个w,那么会影响更上面的祖先,所以我们在考虑将 val[father[lca]]-=w , 这样加上lca传上来的w就相互抵消了,再之后的祖先就不会影响了

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
#define N 50100
int fa[N] , father[N]; int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
int first[N] , k;
struct Edge{
int y , next;
}e[N<<]; void add_edge(int x , int y)
{
e[k].y = y , e[k].next = first[x];
first[x] = k++;
} int _first[N] , _k;
struct QEdege{
int y , next , w , lca;
}qe[N<<]; void add_que_edge(int x , int y , int w)
{
qe[_k].y = y , qe[_k].next = _first[x] , qe[_k].w = w , qe[_k].lca=;
_first[x] = _k++;
}
bool vis[N]; void tarjan(int u , int f)
{
vis[u] = true , fa[u]=u , father[u] = f;
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(vis[v]) continue;
tarjan(v , u);
fa[v] = u;
}
for(int i=_first[u] ; ~i ; i=qe[i].next){
int v = qe[i].y;
if(vis[v]){
int lca = find(v);
qe[i].lca = qe[i^].lca = lca;
}
}
} int val[N] , n , m; void dfs(int u , int f)
{
for(int i=first[u] ; ~i ; i=e[i].next){
int v = e[i].y;
if(v == f) continue;
dfs(v , u);
val[u] += val[v];
}
} int main()
{
// freopen("in.txt" , "r" , stdin);
int cas , x , y , w;
scanf("%d" , &cas);
for(int i= ; i<=cas ; i++){
scanf("%d" , &n);
memset(first , - , sizeof(first));
k=;
memset(_first , - , sizeof(_first));
_k=;
for(int j= ; j<n ; j++){
scanf("%d%d" , &x , &y);
x++ , y++;
add_edge(x , y);
add_edge(y , x);
}
scanf("%d" , &m);
for(int j= ; j<m ; j++){
scanf("%d%d%d" , &x , &y , &w);
x++ , y++;
add_que_edge(x , y , w);
add_que_edge(y , x , w);
}
memset(vis , , sizeof(vis));
tarjan( , );
memset(val , , sizeof(val));
for(int j= ; j<_k ; j+=){
val[qe[j].lca] -= qe[j].w;
if(qe[j].lca!=father[qe[j].lca]) val[father[qe[j].lca]] -= qe[j].w;
val[qe[j].y] += qe[j].w , val[qe[j^].y] += qe[j].w;
// cout<<j<<" "<<qe[j].y<<" "<<qe[j^1].y<<" "<<qe[j].w<<" "<<qe[j].lca<<" "<<fa[qe[j].lca]<<endl;
}
dfs( , );
printf("Case #%d:\n" , i);
for(int j= ; j<=n ; j++) printf("%d\n" , val[j]);
}
return ;
}

LA 5061 LCA tarjan 算法的更多相关文章

  1. [CF 191C]Fools and Roads[LCA Tarjan算法][LCA 与 RMQ问题的转化][LCA ST算法]

    参考: 1. 郭华阳 - 算法合集之<RMQ与LCA问题>. 讲得很清楚! 2. http://www.cnblogs.com/lazycal/archive/2012/08/11/263 ...

  2. 最近公共祖先LCA(Tarjan算法)的思考和算法实现

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  3. POJ 1330 Nearest Common Ancestors(LCA Tarjan算法)

    题目链接:http://poj.org/problem?id=1330 题意:给定一个n个节点的有根树,以及树中的两个节点u,v,求u,v的最近公共祖先. 数据范围:n [2, 10000] 思路:从 ...

  4. LCA:Tarjan算法实现

    本博文转自http://www.cnblogs.com/JVxie/p/4854719.html,转载请注明出处 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有 ...

  5. Tarjan 算法求 LCA / Tarjan 算法求强连通分量

    [时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...

  6. 最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

    LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了f ...

  7. 最近公共祖先 LCA Tarjan算法

    来自:http://www.cnblogs.com/ylfdrib/archive/2010/11/03/1867901.html 对于一棵有根树,就会有父亲结点,祖先结点,当然最近公共祖先就是这两个 ...

  8. HDU 2586 ( LCA/tarjan算法模板)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:n个村庄构成一棵无根树,q次询问,求任意两个村庄之间的最短距离 思路:求出两个村庄的LCA,d ...

  9. LCA - Tarjan 算法

    void dfs(int u) { ; i <= n; i++) { if(visit[i]&&ask[u][i]) { LCA[u][i] = Find(i); } } vis ...

随机推荐

  1. Eclipse NDK 配置

    一.关于NDK:NDK全称:Native Development Kit. 1.NDK是一系列工具的集合. NDK提供了一系列的工具,帮助开发者快速开发C(或C++)的动态库,并能自动将so和java ...

  2. h5 input file ajax实现文件上传

    <input type="file" accept="image/*" height="0" class="file_inp ...

  3. OpenGL的几何变换[转]

    OpenGL的几何变换 1.实验目的: 理解掌握一个OpenGL程序平移.旋转.缩放变换的方法. 2.实验内容: (1)阅读实验原理,运行示范实验代码,掌握OpenGL程序平移.旋转.缩放变换的方法: ...

  4. Hbase之更新单条数据

    import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; impo ...

  5. request获取ip数据

    http://www.cnblogs.com/icerainsoft/p/3584532.html

  6. ListView配合BaseAdapter

    BaseAdapter使用比较麻烦,它是个抽象类,需要重写4个方法分别是getCount() getItem(..) getItemId(..) getVew(..),相应的使用BaseAdapter ...

  7. java的IO流

    java的IO流继承四大抽象类分别是字节流 inputStream outputStream与字符流 read write.怎么理解记忆很重要. 直接连接读写对象的是结点流,例如对文件读取字节类的名字 ...

  8. 生物信息 perl 脚本实战

    索引 1.统计fasta.fa和fastq文件的长度,统计fastq的reads个数,单个reads长度,reads总长度:统计fasta文件中contig的个数,列出名称,单条的长度,以及总长度. ...

  9. js控制手机号码中间用星号代替

    $("#tel").html($("#tel").substring(0,3)+"****"+$("#tel").sub ...

  10. hdu 3038 How Many Answers Are Wrong ( 带 权 并 查 集 )

    How Many Answers Are Wrong Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Ja ...