51NOD1743 JZOJ4899 雪之國度

2021-07-24 15:43:24 字數 1512 閱讀 8033

給定

n 個點,

m條邊的無向圖。每個點有點權wi

,一條邊(x

,y) 的邊權定義為|w

x−wy

| 。 有q

詢問,每次詢問兩個點(x

,y),如果

x 和

y之間存在至少兩條互不相交(沒有重複邊)的路徑,那麼輸出這兩條路徑上邊權的最大值(如果有多對路徑,選擇最小的),否則輸出−1

。3≤n

≤105,

3≤m≤

5×105

,1≤q

≤105

考慮一種最暴力的做法,按邊權從小到大插入邊,動態維護邊雙連通分量。連通分量內的答案可以瞎處理。然而這樣很難維護。

怎麼辦呢?用最小生成樹來維護乙個聯通性,這樣然後在樹上可以更方便的處理邊雙內路徑的最大權值。我們可能會加入某些邊使得它有環,那麼環內權值就要變成加入這條邊的權值(加入邊肯定更大)。但是修改過一次的邊我們就不能再修改了,因為顯然它達到了條件且不會更優。因此我們使用並查集來將所有修改過的點並在一起,這樣修改時就可以暴力沿著並查集父親修改了。

處理詢問的話,倍增查詢路徑最大值即可。

時間複雜度o(

nlog2n

) 。

#include 

#include

#include

#include

#include

using

namespace

std;

int read()

int buf[30];

void write(int x)

const

int n=100050;

const

int m=500050;

const

int e=n<<1;

const

int lgn=17;

struct edge

e[m];

bool

operator

<(edge a,edge b)

void insert(int x,int y,int z)

void dfs(int x)

void pre()

int adjust(int x,int d)

void getans(int x,int y)

int main()

}anc[1][0]=0,deep[1]=1,dfs(1);

for (int i=1;i<=n;i++) fa[i]=i;

for (int i=1,x,y;i<=m;i++)

if (!chosen[i])

for (x=getfather(e[i].x),y=getfather(e[i].y);x!=y;x=getfather(x))

pre();

for (int x,y;q--;)

fclose(stdin),fclose(stdout);

return

0;}

51nod1743 雪之國度

對於乙個無向圖,邊有邊權。對於每組詢問u v,如果可以找到兩條從u到v不相交的路徑,輸出路徑上邊權最大值的最小值。我們考慮到,如果按照邊權從小到大加邊,第一次使得u和v處在同乙個邊雙聯通分量時我就求得了答案。考慮乙個很強的方法,用lct或啟發式合併維護森林,動態維護雙連通分量。因為不可能去持久化 二...

JZOJ 雜題選講 51nod1790

有乙個初始為0的計數器n,每次有兩種操作 n 1 把n不含前導0的二進位制接到字串s的末尾 目標是把s變成給出的字串x 求方案數和最小步數 x 5000 設f i j 表示放到x的第i位,n為 j,i 的方案,最小值同理 每次列舉上乙個位置轉移,這樣是o x 3 並且不好判斷二進位制數的大小 按x的...

51nod 4級演算法 1405

給定一棵無根樹,假設它有n個節點,節點編號從1到n,求任意兩點之間的距離 最短路徑 之和。第一行包含乙個正整數n n 100000 表示節點個數。後面 n 1 行,每行兩個整數表示樹的邊。output每行乙個整數,第i i 1,2,n 行表示所有節點到第i個點的距離之和。4 1 23 2 4 253...