題目大意:對一棵有n(n<=10000)個點的樹若干次操作,每次操作可以把第i條邊的權值改為w,或者求u節點到v節點的路徑上所有邊的最大權值。
解題思路:對這棵樹進行樹鏈剖分,然後用線段樹維護區間最大值。
樹鏈剖分理解:通過規定一種特殊的次序,將樹形結構變為線性結構,從而可以用多種資料結構來解決樹上路徑方面的問題。
ac**:
/*@author: wchhlbt
@date: 2017/7/22
*/#include #define fori(x) for(int i=0;ip;
const double pi = acos(-1.0);
int dx[4] = ;
int dy[4] = ;
int n,m;
int ans;
int cnt;
struct edge
}edge[maxn];
vectore[maxn];
/*樹鏈剖分
cnt初始化為0
son陣列初始化為-1
getans()根據實際維護的值進行修改
*/int son[maxn];//重兒子
int size[maxn];//子數大小
int fa[maxn];//父節點
int dep[maxn];//深度
void dfs1(int u, int f, int d)//維護重兒子,深度,父節點,子樹大小
}int id[maxn];
int top[maxn];
//dfs2建立重鏈
void dfs2(int u, int tp)//tp為當前重鏈的起始點
int update(int root, int pos, int val)//將pos位置的值替換為val
int query(int root, int l, int r)
int temp = query(1,id[tp1],id[u]);//考慮tp1上面的輕鏈
ans = max(ans,temp);
u = fa[tp1]; tp1 = top[u];//更新u節點為重鏈頭節點的父節點
}if(u==v) return ans;
//處理u、v在一條重鏈上的情況
if(dep[v]>dep[u]) swap(u,v),swap(tp1,tp2);
int temp = query(1,id[son[v]],id[u]);
ans = max(ans,temp);
return ans;
}void init()//全部初始化操作
{ cnt = 0;//重新編號樹上的id
memset(son,-1,sizeof(son));
for(int i = 0; i
SPOJ375 樹鏈剖分
題目 query on a tree 題意 給定一棵樹,告訴了每條邊的權值,然後給出兩種操作 1 把第i條邊的權值改為val 2 詢問a,b路徑上權值最大的邊 分析 本題與hdu3966差不多,區別就是 hdu3966是告訴樹中點權的值,這裡是邊權。所以我們可以轉化,用邊的孩子節點來表示該邊。inc...
spoj375 樹鏈剖分
第一次寫樹鏈剖分的題目,下面說下我對樹鏈剖分的理解 以spoj為例,題意是給你一棵樹,有兩種操作,一種是修改某條邊的權值,一種是詢問節點a到節點b之間的路徑上所有邊的最大路徑。處理以上所有的資訊只需要兩個dfs就可以 第乙個dfs,dfs1處理father,size,depth,son 如下 voi...
SPOJ375 樹鏈剖分
題目 query on a tree 題意 給定一棵樹,告訴了每條邊的權值,然後給出兩種操作 1 把第i條邊的權值改為val 2 詢問a,b路徑上權值最大的邊 分析 本題與hdu3966差不多,區別就是 hdu3966是告訴樹中點權的值,這裡是邊權。所以我們可以轉化,用邊的孩子節點來表示該邊。inc...