树链剖分_基于边权

  1 /*
  2   题意:
  3   题解:
  4   时间:
  5 */
  6 
  7 #include <bits/stdc++.h>
  8 using namespace std;
  9 
 10 typedef long long LL;
 11 const int MAXN = 100005;
 12 const LL MOD7 = 1e9+7;
 13 
 14 struct Edge
 15 {
 16     int u,v;
 17     int next;
 18 }edge[2*MAXN];
 19 int head[MAXN];
 20 int cnt;
 21 int top[MAXN];
 22 int fa[MAXN];
 23 int num[MAXN];
 24 int son[MAXN];
 25 int deep[MAXN];
 26 int p[MAXN];
 27 int fp[MAXN];
 28 int pos;
 29 
 30 void init()
 31 {
 32     cnt=0;
 33     memset(head,-1,sizeof(head));
 34     pos=1;
 35     memset(son,-1,sizeof(son));
 36 }
 37 
 38 void addEdge(int u,int v)
 39 {
 40     edge[cnt].u=u;edge[cnt].v=v;edge[cnt].next=head[u];head[u]=cnt++;
 41 }
 42 
 43 void dfs1(int u,int pre,int depth)
 44 {
 45     fa[u]=pre;
 46     deep[u]=depth;
 47     num[u]=1;
 48     for (int i=head[u];i!=-1;i=edge[i].next)
 49     {
 50         int v=edge[i].v;
 51         if (v==pre) continue;
 52         dfs1(v,u,depth+1);
 53         num[u]+=num[v];
 54         if (son[u]==-1 || num[v]>num[son[u]]) son[u]=v;
 55     }
 56 }
 57 
 58 void dfs2(int u,int sp)
 59 {
 60     top[u]=sp;
 61     p[u]=pos++;
 62     fp[p[u]]=u;
 63     if (son[u]==-1) return;
 64     dfs2(son[u],sp);
 65     for (int i=head[u];i!=-1;i=edge[i].next)
 66     {
 67         int v=edge[i].v;
 68         if (son[u]!=v && v!=fa[u]) dfs2(v,v);
 69     }
 70 }
 71 
 72 struct TreeNode
 73 {
 74     int l,r;
 75     int Max;
 76 }segtree[4*MAXN];
 77 
 78 void build(int t,int l,int r)
 79 {
 80     segtree[t].l=l;
 81     segtree[t].r=r;
 82     segtree[t].Max=0;
 83     if (l==r) return;
 84     int mid =(l+r)/2;
 85     build(2*t,l,mid);
 86     build(2*t+1,mid+1,r);
 87 }
 88 
 89 void pushUp(int t)
 90 {
 91     segtree[t].Max = max(segtree[2*t].Max,segtree[2*t+1].Max);
 92 }
 93 
 94 void update(int t,int l,int r,int val)
 95 {
 96     if (segtree[t].l==l && segtree[t].r==r)
 97     {
 98         segtree[t].Max=val;
 99         return;
100     }
101     int mid=(segtree[t].l+segtree[t].r)/2;
102     if (r<=mid) update(2*t,l,r,val);
103     else if (l>mid) update(2*t+1,l,r,val);
104     else update(2*t,l,mid,val),update(2*t+1,mid+1,r,val);
105     pushUp(t);
106 }
107 
108 int query(int t,int l,int r)
109 {
110     if (segtree[t].l==l && segtree[t].r==r)
111     {
112         return segtree[t].Max;
113     }
114     int mid=(segtree[t].l+segtree[t].r)/2;
115     if (r<=mid) return query(2*t,l,r);
116     else if (l>mid) return query(2*t+1,l,r);
117     else return max(query(2*t,l,mid),query(2*t+1,mid+1,r));
118 }
119 
120 int Find(int u,int v)
121 {
122     int f1=top[u],f2=top[v];
123     int tmp=0;
124     while (f1!=f2)
125     {
126         if (deep[f1]<deep[f2])
127         {
128             swap(f1,f2);
129             swap(u,v);
130         }
131         tmp = max(tmp, query(1, p[f1],p[u]));
132         u=fa[f1];
133         f1=top[u];
134     }
135     if (u==v) return tmp;
136     if (deep[u]>deep[v]) swap(u,v);
137     return max(tmp, query(1,p[son[u]],p[v]));
138 }
139 
140 int e[MAXN][3];
141 int n;
142 int main()
143 {
144 #ifndef ONLINE_JUDGE
145     freopen("test.txt","r",stdin);
146 #endif // ONLINE_JUDGE
147     int Case;
148     scanf("%d",&Case);
149     while (Case--)
150     {
151         init();
152         scanf("%d",&n);
153         for (int i=0;i<n-1;++i)
154         {
155             scanf("%d%d%d",&e[i][0],&e[i][1],&e[i][2]);
156             addEdge(e[i][0],e[i][1]);
157             addEdge(e[i][1],e[i][0]);
158         }
159         dfs1(1,0,0);
160         dfs2(1,1);
161         build(1,0,pos-1);
162         for (int i=0;i<n-1;++i)
163         {
164             if (deep[e[i][0]] > deep[e[i][1]])
165                 swap(e[i][0],e[i][1]);
166             update(1,p[e[i][1]],p[e[i][1]],e[i][2]);
167         }
168         char op[10];
169         int u,v;
170         while (scanf("%s",op)==1)
171         {
172             if (op[0]=='D') break;
173             scanf("%d%d",&u,&v);
174             if (op[0]=='Q')
175                 printf("%d\n",Find(u,v));
176             else
177                 update(1,p[e[u-1][1]],p[e[u-1][1]],v);
178         }
179     }
180     return 0;
181 }

 

转载于:https://www.cnblogs.com/LeeSongt/p/9329791.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值