hdu5441 離線處理 並查集

2021-07-05 22:30:58 字數 1572 閱讀 6343

題意 

給你n個城市m個邊,每條邊有一權值,表示路費

如果給出一筆錢,錢大於路費則表示該條路可以通過

通過這條路 則代表 點 (a,b)  和(b,a)是合法的點,合法的對數為2

k次查詢,每次查詢給出一筆錢,求該筆錢能走過的所有點的合法對數

對輸入的邊按權值排序,對輸入的錢數按權值排序

對第一筆錢,把權值比錢小的邊 全都加到乙個並查集,

設兩端點為t1,t2

intf1=findx(t1);

intf2=findx(t2);

bin[f1]=f2;

那麼也就是說,把t1,t2所在的兩個聯通塊合併了,新的根節點為f2,

所以兩個聯通塊新增加的邊數,為f1塊的點乘上f2快的每乙個點,並且由於x,y和y,x算兩對點,所以總的為2*f[f1]*f[f2]//f一直維護的是 該聯通塊的節點的個數

並且累計新增的合法對數  sum+=2*f[f1]*f[f2]   //      f1,f2為兩個端點在並查集中的根節點  

並且輔助陣列f[f2]+=f[f1]    //必須是f1,f2,不能是t1,t2   此時就維護該新的聯通塊的節點個數,因為f1塊已經被合併到f2塊,就沒必要維護了(再也不會訪問到)

-------

對這筆錢做完操作後記錄下sum,轉入下一筆錢,由於已經排序了,下筆錢大於等於本筆錢,一定能覆蓋 之前算過的點,

所以只需要利用之前的結果,在原來已經新增了的邊的基礎上直接繼續新增邊,在原sum上直接累加直到所有邊遍歷完

最終複雜度o(n)

最後按要求輸出答案即可、

#include using namespace std;

struct node

q[5005] , arr[100005];

int f[20005] , bin[20005]; ///f塊的個數 , bin父節點

int ans[5005];

bool cmp(node n1 , node n2)

int find(int x)

int main()

for(int i = 1 ; i <= m ; i++)

for(int i = 1 ; i <= q ; i ++)

sort(arr + 1 , arr + 1 + m , cmp);

sort(q + 1 , q + 1 + q , cmp);

int sum = 0 , j = 1;

for(int i = 1 ; i <= q ; i ++)

j++;

}ans[q[i].index] = sum;

}for(int i = 1 ; i <= q ; i ++)

}}

hdu 3938 Portal 離線 並查集

題意描述 簡單的講就是,給你一張無向圖,求有多少條路徑使得路徑上的花費小於l,這裡路徑上的花費是這樣規定的,a b兩點之間的多條路徑中的最長的邊最小值!思路 原理最小生成樹,相通的點是乙個集合,兩個集合合併的時候,裡面的點數乘積就是合併之後的路徑數 include include includeus...

HDU 3938 Portal (並查集 離線)

兩點之間建立傳送門需要的能量為他們之間所有路徑裡最小的t,一條路徑的t為該路徑上最長的邊的長度。現在 q 個詢問,問 l 能量可以選擇多少種不同點對?因為小的能量找出的點對,在大的能量下肯定也能建立傳送門,因此把詢問記下來,按詢問的能量從小到大計算,這樣離線處理。從小到大列舉新增每條能量不超過當前能...

HDU 3938 Portal 並查集,離線

題目鏈結 查詢有多少對 x,y 使得x到y至少存在一條路徑,路徑上的邊權值最大值不超過l。從小到達依次列舉各個邊,就能得到若干個圖,圖里的每條邊都不大於當前的最大邊 廢話 但是問題在於如何求出每次新加入一條邊之後的點的對數,因為所有的邊不一定是全都連線一起的。如果一條邊把乙個點連入乙個圖里的話,那麼...