乙個圖有
n 個點,
m條無向邊,其中第
i 條邊的權值是ci
。 有q 個詢問,每次給定乙個區間[l
i,ri
],請你計算出只選擇(編號在)這個區間內的邊,在使圖中連通塊數目盡量小的前提之下,選擇的邊的權值和的最小值。1≤
n≤102
,1≤m
≤105,
1≤q≤
1.5×104
顯然題目是求區間內的邊的最小生成森林的邊權和。
可以發現最小生成樹(森林)具有可合併性。
乙個很顯然的想法:將所有邊按照編號分塊,設每一塊大小為
b ,令fi
,j表示從第
i 個塊到第
j個塊的邊構成的最小生成森林的邊集,這個可以o(
n(mb
)2) 的時間複雜度完成。
然後詢問時直接拿出跨塊的
f 值以及兩邊多出來的邊合併一下就好了。 b取
m−−√
的話,時間複雜度可以做到o(
nm+q
(n+m
−−√)
(log(n
+m−−
√)+α
(n))
) (如果你實現得好一點,用歸併排序可以省掉
log )。
不過這個方法還是太*****了,我們把分塊換成線段樹就可以在o(
n(m+
q)logmα(
n)) 的時間複雜度內解決問題。
於是我依然特別*****地打了分塊。
#include
#include
#include
#include
#include
using
namespace
std;
int read()
int buf[30];
void write(int x)
const
int n=105;
const
int m=100005;
const
int b=500;
int srt[m],id[m];
int fa[n],rank[n];
int mst[b][b][n];
int st[b],en[b];
int edg[m][3];
int n,m,q,cnt,bs,bcnt;
int getfather(int son)
void merge(int x,int y)
int kruscal(int *e)
return ret;
}void block()
for (int i=1;ifor (int j=i+1;j<=bcnt;++j)
}int main()
}if (lid) for (int i=1;i<=mst[lid][rid][0];++i) id[++cnt]=mst[lid][rid][i];
}fclose(stdin),fclose(stdout);
return
0;}
506 相對名次
給出 n 名運動員的成績,找出他們的相對名次並授予前三名對應的獎牌。前三名運動員將會被分別授予 金牌 銀牌 和 銅牌 gold medal silver medal bronze medal 注 分數越高的選手,排名越靠前。示例 1 輸入 5,4,3,2,1 輸出 gold medal silver...
506 相對名次(字典)
1.問題描述 給出 n 名運動員的成績,找出他們的相對名次並授予前三名對應的獎牌。前三名運動員將會被分別授予 金牌 銀牌 和 銅牌 gold medal silver medal bronze medal 注 分數越高的選手,排名越靠前。示例 1 輸入 5,4,3,2,1 輸出 gold medal...
Zjr506的捕貓計畫
zjr506很喜歡貓,某一天他突然心血來潮,想捕捉學校裡活動的貓。為了捕貓,zjr506在校園中放置了n個木樁,當他見到有貓進入他的狩獵範圍後,就會以迅雷不及掩耳的速度在一些木樁之間繞上藩籬以困住這些貓。一段時間後,zjr506在繞了m個藩籬後興高采烈的離開了。作為正義的使者,ztxz16不忍心看到...