luogu P4949 最短距離

2022-08-05 01:33:17 字數 2115 閱讀 6559

給出乙個 n 個點 n 條邊的無向連通圖。

你需要支援兩種操作:

修改 第 x 條邊的長度為 y ;

查詢 點 x 到點 y 的最短距離。

共有 m 次操作。

輸入格式:

輸入共 n + m + 1 行:

第 1 行,包含 2 個正整數 n,m,表示點數即邊數,操作次數。

第 2 行到第 n + 1 行,每行包含 3 個正整數 x,y,z,表示 x 與 y 間有一條長度 為 z 的邊。

第 n + 2 到 n + m + 1 行,每行包含 3 個正整數 opt,x,y,表示操作種類,操作的引數(含義見【題目描述】)。

輸出格式:

對於每次操作 2 輸出查詢的結果。

此題是一道基環樹上樹鏈剖分題目

思路是這樣的:基環樹其實可以看做一棵樹多連了一條邊,於是我們可以通過加邊時維護乙個並查集,來找出多的那條邊。

將那條多出的邊記錄下來。

然後我們考慮u到v的最大值,有兩種情況

u直接在樹上到v

u,v到多出的那條邊的兩端,通過這條邊連在一起

與是我們就可以很愉快的在樹上跑樹鏈剖分了,注意此題是邊權而不是點權

那我們對於u到v權值為w的一條邊可以看做u->xx->v,u,v點權為0,xx點權為w,就可將邊權轉化為點權了,點數翻倍,記得陣列大小翻倍喲

值得一提的是我一開始線段樹的陣列忘記開4倍了,結果又wa又tle40分,搞得我還以為**寫錯了呢

實現如下:

#include #include 

#include

#include

#include

#include

#define lson l,mid,o<<1

#define rson mid+1,r,o<<1|1

using

namespace

std;

typedef

long

long

ll;inline

intread()

const

int n=200100

;int n,q,op,u,v,w,cnt,sum[n<<2],head[n],top[n],fe[n],fa[n],id[n],dep[n],size[n],son[n],ww[n],wn[n],tim=0

,t1,t2,keu,kev,kew,kex,xu;

int getf(int u)

struct edgee[n<<1

];void add(int u,int v);head[u]=cnt;}

void build(int l,int r,int

o)

int mid=(l+r)>>1

; build(lson);build(rson);

sum[o]=sum[o<<1]+sum[o<<1|1];}

void update(int pre,int val,int l,int r,int

o)

int mid=(l+r)>>1

;

if(pre<=mid) update(pre,val,lson);

else

update(pre,val,rson);

sum[o]=sum[o<<1]+sum[o<<1|1];}

int query(int l,int r,int l,int r,int

o)int query_tree(int u,int

v)

if(dep[u]>dep[v]) swap(u,v);

return ans+query(id[u],id[v],1,n,1);}

void dfs1(int u,int

ff)}

void dfs2(int u,int

topf)

intmain()

else }n

<<=1

; dfs1(

1,1);dfs2(1,1);build(1,n,1

);

int ans=0

;

while(q--)

else

}return0;

}

洛谷P4949 最短距離

給出乙個 n 個點 n 條邊的無向連通圖。你需要支援兩種操作 修改 第 x 條邊的長度為 y 查詢 點 x 到點 y 的最短距離。共有 m 次操作。思路 n個點n條邊的無向連通圖 簡單圖 如果少一條邊就是形成一棵樹,就是一道lca題,這題多了一條邊,就要用相應的方法處理這條邊。考慮剔除的邊是 uu,...

1407 最短距離

兩個點 a b 均在做勻速直線運動。給出 t 0時刻 a b 的座標,以及 a b 的速度,計算t 0時兩個點的距離的最小值。輸入的第一行包含乙個整數 t 1 t 200 表示一共有 t 組測試資料。對於每組測試資料,第一行包含4個整數 x a y a v ax v ay 103 x a y a v...

編輯最短距離

給定兩個字串s和t,對於t我們允許三種操作 1 在任意位置新增任意字元 2 刪除存在的任意字元 3 修改任意字元 問最少操作多少次可以把字串t變成s?例如 s abcf t dbfg 那麼我們可以 1 把d改為a 2 刪掉g 3 加入c 所以答案是3。1 把t中字元全刪了,再新增s的全部字元,操作次...