POJ 3237
2015-08-27 17:26
357 查看
题目大意:指定一颗树上有3个操作:询问操作,询问a点和b点之间的路径上最长的那条边的长度;取反操作,将a点和b点之间的路径权值都取相反数;变化操作,把某条边的权值变成指定的值。
#include <cstdio> #include <iostream> #include <cstring> using namespace std; #define N 10010 #define ls o<<1 #define rs o<<1|1 #define define_m int m=(l+r)>>1 const int INF = 2000000000; int first , k; struct Edge{ int x , y , next , w; Edge(){} Edge(int x , int y , int next , int w):x(x),y(y),next(next),w(w){} }e[N<<1]; void add_edge(int x ,int y , int w) { e[k] = Edge(x , y , first[x] , w); first[x] = k++; } int sz , son , dep , fa , num , id , top ; void dfs(int u , int f , int d) { sz[u] = 1 , fa[u] = f , son[u] = 0 , dep[u] = d; int maxn = 0; for(int i=first[u] ; ~i ; i=e[i].next){ int v = e[i].y; if(v == f) continue; dfs(v , u , d+1); sz[u] += sz[v]; if(maxn<sz[v]) maxn = sz[v] , son[u] = v; } } void dfs1(int u , int f , int head) { id[u] = ++num , top[u] = head; if(son[u]) dfs1(son[u] , u , head); for(int i=first[u] ; ~i ; i=e[i].next){ int v = e[i].y; if(v == f || v==son[u]) continue; dfs1(v , u , v); } } int mx[N<<2] , mn[N<<2] , neg[N<<2] , val ; void push_down(int o) { if(neg[o]<0){ neg[ls]*=neg[o] , neg[rs]*=neg[o]; int tmp; tmp = mx[ls] , mx[ls] = -mn[ls] , mn[ls] = -tmp; tmp = mx[rs] , mx[rs] = -mn[rs] , mn[rs] = -tmp; neg[o] = 1; } } void push_up(int o) { mx[o] = max(mx[ls] , mx[rs]); mn[o] = min(mn[ls] , mn[rs]); } void build(int o , int l , int r) { neg[o] = 1; if(l==r){ mx[o] = mn[o] = val[l]; return ; } define_m; build(ls , l , m); build(rs , m+1 , r); push_up(o); } void change(int o , int l , int r , int p , int v) { if(l==r){ mx[o] = mn[o] = v; return; } push_down(o); define_m; if(m>=p) change(ls , l , m , p , v); else change(rs , m+1 , r , p , v); push_up(o); } void update(int o , int l , int r , int s , int t) { if(l>=s && r<=t){ int tmp; tmp = mx[o] , mx[o] = -mn[o] , mn[o] = -tmp; neg[o] *= -1; return ; } push_down(o); define_m; if(m>=s) update(ls , l , m , s , t); if(m<t) update(rs , m+1 , r , s , t); push_up(o); } int query(int o , int l , int r , int s , int t) { if(l>=s && r<=t) return mx[o]; push_down(o); define_m; int ans = -INF; if(m>=s) ans=max(ans , query(ls , l , m , s , t)); if(m<t) ans=max(ans , query(rs , m+1 , r , s , t)); return ans; } int n , u , v , w; char str[10]; void negatePath(int u , int v) { int top1 = top[u] , top2 = top[v]; while(top1!=top2) { if(dep[top1]<dep[top2]){ swap(top1 , top2); swap(u , v); } update(1 , 2 , num , id[top1] , id[u]); u = fa[top1]; top1 = top[u]; } if(u!=v){ if(dep[u]<dep[v]) swap(u , v); update(1 , 2 , num , id[son[v]] , id[u]); } } int calPath(int u , int v) { int top1 = top[u] , top2 = top[v]; int ret = -INF; while(top1!=top2){ if(dep[top1]<dep[top2]){ swap(top1 , top2); swap(u , v); } ret = max(ret , query(1 , 2 , num , id[top1] , id[u])); u = fa[top1]; top1 = top[u]; } if(u!=v){ if(dep[u]<dep[v]) swap(u , v); ret = max(ret , query(1 , 2 , num , id[son[v]] , id[u])); } return ret; } int main() { // freopen("in.txt" , "r" , stdin); int T; scanf("%d" , &T); while(T--) { scanf("%d" , &n); memset(first , -1 , sizeof(first)); k=0; for(int i=0 ; i<n-1 ; i++){ scanf("%d%d%d" , &u ,&v , &w); add_edge(u , v , w); add_edge(v , u , w); } num = 0; dfs(1 , 0 , 1); dfs1(1 , 0 , 1); for(int i=0 ; i<n ; i++){ int j=i<<1 , x=e[j].x , y=e[j].y; if(fa[x]!=y) val[id[y]] = e[j].w; else val[id[x]] = e[j].w; } build(1 , 2 , num); while(scanf("%s" , str)){ if(str[0] == 'D') break; if(str[0] == 'C'){ scanf("%d%d" , &u , &v); u--; int x = e[u*2].x , y = e[u*2].y , pos; if(fa[x]!=y) pos = id[y]; else pos = id[x]; change(1 , 2 , num , pos , v); } else if(str[0] == 'N'){ scanf("%d%d" , &u , &v); negatePath(u , v); } else{ scanf("%d%d" , &u , &v); int ret = calPath(u , v); printf("%d\n" , ret); } } } return 0; }
相关文章推荐
- 日常错误积累
- axis service没有配置namesapce 如何设置QName namesapce
- C++类的继承笔记
- GIS 四参数 七参数
- 'telnet' 不是内部或外部…
- Allocate exception for…
- Tomcat网站主机绑定域名
- DIV自适应高度
- 三步解决端口占用
- js设置div的class, 在360浏览…
- Mysql中文查询没有结果
- 在Eclipse中启动Tomcat, 访问不了
- 网页背景图片在360浏览器、IE8浏览…
- Android 模拟器安装APK
- Sql server连接2个字段/Arrary
- java摄像头实时摄像程序
- java线程interrupt()方法和线程终止方式
- 如何引用第三方提供的.so库文件以及如何使用javah生成.h文件
- 鼠标绘制矩形
- c++对象模型-对象模型