題目大意:有n
個城市,城市之間有
m條道路,每條道路用時為t。有
q次詢問,每次詢問在時間
t內可以在多少對城市之間走動。注意
(a,b)
和(b,a)
算兩種方案。
題目分析:我們可以知道,如果n
個城市之間相互聯通,那麼方案數一共有
n*(n-1)
個,所以現在我們要求的就是在
t範圍內有多少城市相互聯通以及有多少組。想到用並查集來做,並查集剛好可以計算出聯通分量的個數以及每個連通分量的個數。
假設現在有兩個連通分量個數分別為n,m
,每個分量之間可以走動的城市對已經計算出來了,現在增加一條路徑之後這兩個分量連通了,那麼增加的城市對有多少種呢。我們可以想到,n和
m從互不相干到互相連通,所以增加的城市對數是
n*m,在乘上
2。網上有人說是
(n+m)*(n+m-1)-n*(n-1)-m*(m-1),
因為連通之前兩個分量可以走動的城市樹分別為
n*(n-1)
和m*(m-1)
,連通之後為
(n+m)*(n+m-1),
相減就得到上面的結果。其實化簡之後可以看到,兩種方法是一樣的。
有人說,既然我們可以直接計算連通之後的城市對數(利用並查集的得到每個連通分量最後的城市個數n
就可以得到結果為
n*(n-1)),
這種想法是正確的但是很浪費時間。這樣之後還需要統計連通分量的個數以及每個分量的城市數。相對這題來說,效率不高。
之所以利用增加的方法來計算,因為我們可以將q
次詢問排序之後第
i次詢問的時候在
t範圍內構建並查集,這樣在
i+1次詢問的時候可以直接利用前面以及構建好的並查集並直接向裡面新增元素即可。這樣效率高很多。
#include #include #include #include #include #include #include using namespace std;
const int maxn = 100005;
int n,m,q,p[20010];
int a[20010]; //a[i]表示的是結點i的組號,初始值是
int s[20010]; //s[i]表示的是結點i所屬的組中結點的個數(數的大小)
struct node
;node a[maxn],b[20010];
bool cmp(node x , node y)
int find(int p)
return p;
}void union(int p,int q)
{ int proot=find(p);
int qroot=find(q);//獲得p和q的組號
if(proot==qroot) return ;
if(s[proot]
CCPC長春賽區流水賬
day 1 坐了27個小時火車 整個人下車都快崩潰了。出站就感覺到了北方的 涼爽 計程車半個小時就到了賓館,這個賓館的設計簡直是醉了,浴室沒有門是個啥玩意?晚上去了仁風閣,朝鮮妹子真是太溫柔了 早上去報道,領了150塊,內心十分激動。走進日新樓,我有點懵逼。這個真的是食堂?電影院 游泳館 電競中心 ...
2012 ACM ICPC 長春賽區網路賽
1001 a problem with integers 題意 有兩種操作,一種是更新區間a b中a i b and i a k 0 的點加上c 一種是詢問aa 的value 思路 明顯的線段樹 但是依然跪倒啊 cnt i k c 代表當前區間i 每隔k個字元累加c,然後就是更新,如果存在要更新的區...
2015 ICPC長春賽區銅牌題
題意 給出n m的空地,每個空地上給出的數字是用方塊疊起來的高度,在三維空間求出這些用立方體堆起來的表面積,底面積不算。掃三個方向就行,正檢視和側檢視算出來的值都要乘以2。如下 include include include include includeusing namespace std de...