當然這題有很多做法,但是我看到沒有人寫dsu的很驚奇
按照之前做連雙向邊題的經驗,這題可以用並查集維護聯通
然後對於每個詢問\(x,y\),考慮啟發式合併
當兩個點集\(x,y\)合併時,一些涉及到其中點的詢問可以被解決,而遍歷\(x,y\)中的詢問集其實是等價的,所以可以直接用啟發式合併存下這個點集涉及到的詢問,在合併時我們要遍歷陣列,所以可以同時完成對於詢問的回答
typedef long long ll;
#define rep(i,a,b) for(int i=a,i##end=b;i<=i##end;++i)
#define drep(i,a,b) for(int i=a,i##end=b;i>=i##end;--i)
char io;
int rd()
const int n=1e5+10;
int n,m,q;
struct edge
bool operator < (const edge __) const
}e[n];
int ans[n];
struct query;
vector v[n];
int fa[n];
int find(int x)
int main());
v[y].push_back((query));
} rep(i,1,m) else v[y].push_back(v[x][j]);
} }rep(i,1,q) printf("%d\n",ans[i]);
}
非常精簡
如果你不懂啟發式合併的原理,我可以簡單證明一下
對於這些集合,元素總數為m
每一次我們將小的集合合併到大的上面,集合大小至少是兩倍,所以每個元素最多會在log2(m)次合併中被訪問到
總複雜度\(q \cdot log(q)\)
noip2013貨車運輸
貨車運輸 truck.cpp c pas 問題描述 a 國有n座城市,編號從1到n,城市之間有 m條雙向道路。每一條道路對車輛都有重 量限制,簡稱限重。現在有 q輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的 情況下,最多能運多重的貨物。輸入 輸入檔名為truck.in。輸入檔案第一行有兩個...
NOIP 2013 貨車運輸
題目描述 description a 國有 n 座城市,編號從 1 到 n,城市之間有 m 條雙向道路。每一條道路對車輛都有重量限制,簡稱限重。現在有 q輛貨車在運輸貨物,司機們想知道每輛車在不超過車輛限重的情況下,最多能運多重的貨物。輸入描述 input description 第一行有兩個用乙個...
NOIP 2013 貨車運輸
題目大意 給定一張無向圖 以及若干個詢問 對於每個詢問求所有由節點u到節點v的路徑上邊權的最小值的最大值。題解 首先用構造一棵最大生成樹,這樣保證樹上兩個節點路徑邊權的最小值最大 在最大生成樹上兩個節點之間只有一條路徑,所以只需要找路徑上邊權的最小值 為了快速的尋找最小值,利用樹上倍增的想法用f j...