首页 > 代码库 > 【SPOJ Query on a tree 】 (树链剖分)
【SPOJ Query on a tree 】 (树链剖分)
http://acm.hust.edu.cn/vjudge/problem/13013
题意:
有一棵N个节点的树(1<=N<=10000),N-1条边,边的编号为1~N-1,每条边有一个权值,要求模拟两种操作:
1:QUERY x y 求节点x和节点y之间的路径中权值最大的边。
2:CHANGE p k修改第p条边的权值为k。
【分析】
树链剖分裸题。。
【表示我一开始怎么TLE,后来怎么AC的并不知道。。
1 #include<cstdio> 2 #include<cstdlib> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 #include<set> 7 using namespace std; 8 #define Maxn 10010 9 #define INF 0x7fffffff 10 11 int mymax(int x,int y) {return x>y?x:y;} 12 13 struct node 14 { 15 int x,y,c,next; 16 }t[2*Maxn];int len; 17 18 int first[Maxn]; 19 void ins(int x,int y,int c) 20 { 21 t[++len].x=x;t[len].y=y;t[len].c=c; 22 t[len].next=first[x];first[x]=len; 23 } 24 25 char s[110]; 26 27 int son[Maxn],dfn[Maxn],top[Maxn],cnt; 28 int sm[Maxn],fa[Maxn],id[Maxn],dep[Maxn]; 29 void dfs1(int x,int f) 30 { 31 dep[x]=dep[f]+1; 32 sm[x]=1;son[x]=0;fa[x]=f; 33 for(int i=first[x];i;i=t[i].next) if(t[i].y!=f) 34 { 35 int y=t[i].y; 36 dfs1(y,x); 37 sm[x]+=sm[y]; 38 if(son[x]==0||sm[son[x]]<sm[y]) son[x]=y; 39 } 40 } 41 42 void dfs2(int x,int tp) 43 { 44 dfn[x]=++cnt;top[x]=tp; 45 if(son[x]) dfs2(son[x],tp); 46 for(int i=first[x];i;i=t[i].next) if(t[i].y!=fa[x]&&t[i].y!=son[x]) 47 dfs2(t[i].y,t[i].y); 48 } 49 50 struct nnode 51 { 52 int l,r,lc,rc,mx; 53 }tr[2*Maxn];int tot; 54 55 int build(int l,int r) 56 { 57 int x=++tot; 58 tr[x].l=l;tr[x].r=r; 59 int mid=(l+r)>>1; 60 if(l!=r) 61 { 62 tr[x].lc=build(l,mid); 63 tr[x].rc=build(mid+1,r); 64 } 65 tr[x].mx=-INF; 66 return x; 67 } 68 69 void change(int x,int y,int z) 70 { 71 if(tr[x].l==tr[x].r) 72 { 73 tr[x].mx=z; 74 return; 75 } 76 int mid=(tr[x].l+tr[x].r)>>1; 77 if(y<=mid) change(tr[x].lc,y,z); 78 else change(tr[x].rc,y,z); 79 tr[x].mx=mymax(tr[tr[x].lc].mx,tr[tr[x].rc].mx); 80 } 81 82 int query(int x,int l,int r) 83 { 84 if(tr[x].l==l&&tr[x].r==r) return tr[x].mx; 85 int mid=(tr[x].l+tr[x].r)>>1; 86 if(r<=mid) return query(tr[x].lc,l,r); 87 else if(l>mid) return query(tr[x].rc,l,r); 88 return mymax(query(tr[x].lc,l,mid),query(tr[x].rc,mid+1,r)); 89 } 90 91 int get_ans(int x,int y) 92 { 93 int mx=0; 94 while(top[x]!=top[y]) 95 { 96 if(dep[top[x]]<dep[top[y]]) swap(x,y); 97 mx=mymax(mx,query(1,dfn[top[x]],dfn[x])); 98 x=fa[top[x]]; 99 } 100 if(x==y) return mx; 101 if(dep[x]>dep[y]) swap(x,y); 102 mx=mymax(mx,query(1,dfn[x]+1,dfn[y])); 103 return mx; 104 } 105 106 int main() 107 { 108 int T; 109 scanf("%d",&T); 110 while(T--) 111 { 112 int n; 113 scanf("%d",&n); 114 len=0; 115 memset(first,0,sizeof(first)); 116 for(int i=1;i<n;i++) 117 { 118 int x,y,c; 119 scanf("%d%d%d",&x,&y,&c); 120 ins(x,y,c);ins(y,x,c); 121 } 122 dep[0]=0;dfs1(1,0); 123 cnt=0;dfs2(1,1); 124 tot=0;build(1,n); 125 for(int i=1;i<=len;i+=2) 126 { 127 if(fa[t[i].x]==t[i].y) id[(i+1)/2]=t[i].x; 128 else id[(i+1)/2]=t[i].y; 129 change(1,dfn[id[(i+1)/2]],t[i].c); 130 } 131 while(1) 132 { 133 scanf("%s",s); 134 if(s[0]==‘D‘) break; 135 int x,y; 136 scanf("%d%d",&x,&y); 137 if(s[0]==‘C‘) 138 { 139 change(1,dfn[id[x]],y); 140 } 141 else 142 { 143 printf("%d\n",get_ans(x,y)); 144 } 145 } 146 } 147 return 0; 148 }
2017-01-21 11:45:00
【SPOJ Query on a tree 】 (树链剖分)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。