题意:给你一颗树,两个操作,改变某条边的值,求起点到终点路径长度。
解题思路:求值和点略有不同。不过问题不是太大,主要要注意的问题就是 ,用vector 存 链接表 时间太慢了,不如head 存连接表快 ,慢3倍以上
解题代码:
1 // File Name: spoj375.cpp 2 // Author: darkdream 3 // Created Time: 2014年10月09日 星期四 19时50分56秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 //#pragma comment(linker,"/STACK:102400000,102400000") 25 //#define debug 26 #define LL long long 27 #define maxn 100006 28 using namespace std; 29 struct sgnode{ 30 int l,r ; 31 int mx; 32 }tr[maxn << 2]; 33 void pushup(int c) 34 { 35 tr[c].mx =tr[c<<1].mx + tr[(c<<1)|1].mx; 36 } 37 void build(int c, int l ,int r ) 38 { 39 tr[c].l = l ; 40 tr[c].r = r; 41 tr[c].mx = 0 ; 42 if(l == r) 43 return ; 44 int m = (l+r)>>1; 45 build(c<<1,l,m); 46 build((c<<1)|1,m+1,r); 47 } 48 void update(int c, int k,int v) 49 { 50 if(tr[c].l == tr[c].r && tr[c].l == k) 51 { 52 tr[c].mx = v; 53 return; 54 } 55 int m = (tr[c].l +tr[c].r) >> 1; 56 if(k <= m ) 57 update(c<<1,k,v); 58 else 59 update((c<<1)|1,k,v); 60 pushup(c); 61 } 62 int query(int c, int l ,int r) 63 { 64 65 if(tr[c].l >= l && tr[c].r <= r) 66 { 67 return tr[c].mx; 68 } 69 int m = (tr[c].l + tr[c].r) >> 1; 70 if(r <= m) 71 return query(c<<1,l,r); 72 if(l > m) 73 return query((c<<1)|1,l,r); 74 else return query(c <<1,l,m) + query((c<<1)|1,m+1,r); 75 } 76 struct node{ 77 int to,next; 78 }mp[maxn*2]; 79 int head[maxn]; 80 int siz[maxn]; // 子节点的个数 81 int fa[maxn]; // 父亲节点 82 int son[maxn]; // 儿子节点 83 int dep[maxn]; // 深度 84 int top[maxn]; // 85 int w[maxn]; 86 int totw,tote; 87 int n; 88 void addedge(int u ,int v) 89 { 90 mp[tote].to = v ; 91 mp[tote].next = head[u]; 92 head[u] = tote ++;; 93 } 94 void dfs_1(int k , int la,int d) 95 { 96 // printf("%d %d %d\n",k,la,num); 97 dep[k] = d; 98 fa[k] = la; 99 siz[k] = 1 ; 100 son[k] = -1; 101 for(int i = head[k] ;i != -1 ;i = mp[i].next) 102 { 103 if(mp[i].to != la) 104 { 105 dfs_1(mp[i].to,k,d+1); 106 siz[k] += siz[mp[i].to]; 107 if(son[k] == -1 || siz[mp[i].to] > siz[son[k]]) 108 son[k] = mp[i].to ; 109 } 110 } 111 } 112 void dfs_2(int k,int sp ) 113 { 114 top[k] = sp; 115 w[k] = totw ++ ; 116 if(son[k] == -1) return; 117 dfs_2(son[k],sp); 118 for(int i = head[k] ;i != -1 ;i = mp[i].next) 119 { 120 // printf("%d\n",mp[i].to); 121 if(mp[i].to!= son[k] && mp[i].to != fa[k]) 122 dfs_2(mp[i].to,mp[i].to); 123 } 124 } 125 void make() 126 { 127 totw = 0 ; 128 dfs_1(1,0,1); 129 dfs_2(1,1); 130 } 131 struct edges{ 132 int u,v,w; 133 }edge[maxn]; 134 int find(int u ,int v) 135 { 136 int f1 = top[u],f2 = top[v]; 137 int tmp = 0 ; 138 while(f1 != f2) 139 { 140 if(dep[f1] < dep[f2]) 141 { 142 swap(f1,f2); 143 swap(u,v); 144 } 145 tmp +=query(1,w[f1],w[u]); 146 u = fa[f1]; // f1 是他的top 147 f1 = top[u]; 148 } 149 if(u == v ) return tmp; 150 if(dep[u] > dep[v]) 151 swap(u,v); 152 tmp +=query(1,w[son[u]],w[v]); 153 return tmp; 154 } 155 int main(){ 156 int q , s; 157 #ifdef debug 158 159 freopen("out","r",stdin); 160 freopen("2763","w",stdout); 161 162 int be = clock(); 163 #endif 164 int ti = 0; 165 while(scanf("%d %d %d",&n,&q,&s) != EOF) 166 { 167 // fclose(stdout); 168 // printf("******%d\n",++ti); 169 //freopen("2763","w",stdout); 170 memset(head,-1,sizeof(int)*(n+1)); 171 tote = 0 ; 172 for(int i = 1;i < n ;i ++) 173 { 174 // printf("***\n"); 175 scanf("%d %d %d",&edge[i].u,&edge[i].v,&edge[i].w); 176 addedge(edge[i].u,edge[i].v); 177 addedge(edge[i].v,edge[i].u); 178 } 179 make(); 180 //printf("***\n"); 181 build(1,1,totw-1); 182 for(int i = 1;i < n;i ++) 183 { 184 if(dep[edge[i].u] > dep[edge[i].v]) 185 swap(edge[i].u,edge[i].v); 186 //printf("%d %d*\n",w[edge[i].v],edge[i].w); 187 update(1,w[edge[i].v],edge[i].w); 188 } 189 int op; 190 int u,v,uv; 191 u = s; 192 while(q--) 193 { 194 195 scanf("%d",&op); 196 if(op == 0 ) 197 { 198 scanf("%d",&v); 199 // printf("****\n"); 200 printf("%d\n",find(u,v)); 201 u = v; 202 }else{ 203 scanf("%d %d",&v,&uv); 204 update(1,w[edge[v].v],uv); 205 } 206 } 207 } 208 //freopen(stdout,"w",stdout); 209 #ifdef debug 210 int en = clock(); 211 printf("%d\n",en-be); 212 #endif 213 return 0; 214 }
没有梦想,何谈远方