Question link:Http://poj.org/problem? Id = 2763
Theme: Someone starts at S. Q-times of moving, each time it moves along a chain on the tree, each passing edge has a certain cost, which can be modified at will. Ask about the cost of each move.
Solutions:
Tree link splitting basic questions. Change s after each Q.
The line segment tree records edge weights. For an edge (u, v), the edge weight is added to the end where the DEP is relatively large.
Link query (edge) and link query (point) are slightly different in light chains.
Note that in this question, the map saved in the vector adjacent table will be TLE, and the chain forward star should be used. It is a basic requirement to use the chain forward star in tree link splitting.
#include "cstdio"#include "cstring"using namespace std;#define maxn 100005int s[maxn],dep[maxn],w[maxn],fa[maxn],top[maxn],son[maxn],val[maxn],cnt,tol,n;int head[maxn];struct Edge{ int u,v,c;}edge[maxn];struct EDGE{ int next,to;}e[2*maxn];void addedge(int u,int v){ e[tol].to=v; e[tol].next=head[u]; head[u]=tol++;}void dfs1(int u,int pre,int d){ s[u]=1;fa[u]=pre;dep[u]=d; for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(v==pre) continue; dfs1(v,u,d+1); s[u]+=s[v]; if(son[u]!=-1||s[v]>s[son[u]]) son[u]=v; }}void dfs2(int u,int tp){ w[u]=++cnt;top[u]=tp; if(son[u]==-1) return; dfs2(son[u],tp); for(int i=head[u];i!=-1;i=e[i].next) { int v=e[i].to; if(v!=son[u]&&v!=fa[u]) dfs2(v,v); }}//Segment Tree#define lson l,mid,root<<1#define rson mid+1,r,root<<1|1int sum[maxn<<2];void PushUp(int root){ sum[root]=sum[root<<1]+sum[root<<1|1];}void Build(int l,int r,int root){ if(l==r) { sum[root]=val[l]; return; } int mid=(l+r)>>1; Build(lson); Build(rson); PushUp(root);}void Update(int p,int v,int l,int r,int root){ if(l==r) { sum[root]=v; return; } int mid=(l+r)>>1; if(p<=mid) Update(p,v,lson); else Update(p,v,rson); PushUp(root);}int Query(int L,int R,int l,int r,int root){ if(L<=l&&r<=R) return sum[root]; int mid=(l+r)>>1; int ret=0; if(L<=mid) ret+=Query(L,R,lson); if(R>mid) ret+=Query(L,R,rson); return ret;}void Change(int x,int v){ if(dep[edge[x].u]>dep[edge[x].v]) Update(w[edge[x].u],v,1,n,1); else Update(w[edge[x].v],v,1,n,1);}int query(int x,int y){ int ans=0; while(top[x]!=top[y]) { if(dep[top[x]]<dep[top[y]]) swap(x,y); ans+=Query(w[top[x]],w[x],1,n,1); x=fa[top[x]]; } if(dep[x]>dep[y]) swap(x,y); if(x!=y) ans+=Query(w[son[x]],w[y],1,n,1);// return ans;}int main(){ //freopen("in.txt","r",stdin); int m,s,u,t,cmd; while(~scanf("%d%d%d",&n,&m,&s)) { memset(son,-1,sizeof(son)); memset(head,-1,sizeof(head)); cnt=tol=0; for(int i=1;i<n;i++) { scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].c); addedge(edge[i].u,edge[i].v); addedge(edge[i].v,edge[i].u); } dfs1(1,1,1); dfs2(1,1); for(int i=1;i<n;i++) { if(dep[edge[i].u]>dep[edge[i].v]) val[w[edge[i].u]]=edge[i].c; else val[w[edge[i].v]]=edge[i].c; } Build(1,n,1); while(m--) { scanf("%d",&cmd); if(cmd==0) { scanf("%d",&t); printf("%d\n",query(s,t)); s=t; } if(cmd==1) { scanf("%d%d",&u,&t); Change(u,t); } } }}
13493821 |
Neopenx |
2763 |
Accepted |
9676 K |
1579 Ms |
C ++ |
3176b |
16:16:22 |
Poj 2763 (tree link splitting + edge modification + edge query)