POJ 1984 Navigation Nightmare(路徑壓縮並查集)
並查集,給n個點和m條邊,每條邊有方向和長度,再給q個詢問,第i個詢問查詢兩個點之間在Ti時刻時的曼哈頓距離(能連通則輸出曼哈頓距離,否則輸出-1
這題還要注意數據可能不是按照時間順序輸入的,要做按時間順序由小到大排序,然後再按原來的順序輸出。還是路徑壓縮的一套不過這次有兩個r[]數組,rx[i]表示i節點到父親節點的x距離,ry[i]同理,輸入m條邊時,
for (i=1;i<=m;i++)
{
scanf("%d%d%d %c",&x[i],&y[i],&d,&c);
switch(c)
{
case 'W':dx[i]=-d;dy[i]=0;break;//西
case 'S':dx[i]=0;dy[i]=-d;break;
case 'E':dx[i]=d;dy[i]=0;break;
case 'N':dx[i]=0;dy[i]=d;break;
}
}
for (i=1;i<=k;i++)
{
for (;j<=a[i].idx;j++)
{
fx=find(x[j]);fy=find(y[j]);
fa[fy]=fx;
rx[fy]=rx[x[j]]-rx[y[j]]-dx[j];//到根節點的距離,fx在fy左邊爲負,右邊爲正
ry[fy]=ry[x[j]]-ry[y[j]]-dy[j];//上fx在fy上方
爲正,下爲負
}
if (find(a[i].x)!=find(a[i].y))
ans[a[i].n]=-1;
else
ans[a[i].n]=abs(rx[a[i].x]-rx[a[i].y])+abs(ry[a[i].x]-ry[a[i].y]);
}
POJ 2631 Roads in the North(樹的直徑)
求樹上最長的兩個點之間的距離。這裏有一個結論,在圖中,要找到距離最遠的兩點,先隨便從一個點入手bfs,找到距離這個點最遠的點,在從這個點bfs找到距離這點最遠的點,這兩點之間的距離就是這顆樹的直徑。即首先從樹上任意一個點a出發, (BFS)找出到這個點距離最遠的點b. 然後在從b點出發(BFS)找到距離b點最遠的點c. 那麼bc間的距離就是樹的直徑.所以直接進行bfs搜索就行了
poj 1985 Cow Marathon 【樹的直徑】
和上一道題目一樣,裸題。
樹狀數組只能計算A[1]開始的和,A[0]這個元素是不能用的,複雜度O(logn)。執行n次add操作,總時間複雜度O(nlogn)。注意,剛開始c數組要初始全0,然後每讀入一個數A[i]就執行一步add(i, A[i])來進行真正的初始化。
且樹狀數組處理的數組A[n]是從小標1開始的,也即A[0]是一個沒有用的元素。
C數組中的每一個元素都是A數組中的一段連續和。
HDU 1166 敵兵佈陣(簡單樹狀數組)
樹狀數組裸題
UVA1428 Ping pong(樹狀數組)
先別想與樹狀數組有什麼聯繫?先想拿到這個題目怎麼做?很容易想到枚舉誰可以當裁判,但裁判的條件是,假設c是裁判,a,b是對手,則a<=c<=b,即裁判能力值介於比賽者之間,且比賽選手是在裁判住所兩側各挑一個,不能都在同一側,他當裁判時有幾種比賽組織方式。對於第i個裁判,他能組織多少種比賽?
假設a1~a[i-1]有L個能力值比a[i]小的,那麼比a[i]大的i-1-L個
A[i+1]~a[n]有R個能力值比a[i]小的,那麼比a[i]大的有n-i-R個
··················i················
L個小於等於a[i] R個小於等於a[i]
i-1-L個比a[i]大 n-i-R個比a[i]大
顯然,第i個裁判可以組織的比賽場數
L*(n-i-R)+(i-1-L)*R。
問題就轉化成了,對於每個裁判怎麼求其,L,R,這個地方就可以用樹狀數組了。
對每個i,求左邊比他小的數,正着跑一邊,這個數出現了,就在他的位置加1,對於每個數,先求一下比他小的有幾個,再把這個數add進去。
對每個I,求右邊比他小的數,倒着跑一邊,這個輸出現,就在他的位置+1,對於每個數,先求一下比他小的有幾個,再把這個數add進去。
3 4 5 1 1 2爲例
求左邊
C數組
1位置 2位置 3位置 4位置 5位置
0 0 0 0 0
Sum(3)=0,顯然左邊比3小的沒有
Add(3,1)
0 0 1 0 0
Sum(4)=1,顯然左邊比4小的有一個
Add(4,1)
0 0 1 1
Sum(5)=2,顯然左邊比5小的有兩個
Add(5,1)
0 0 1 1 1]
Sum(1)=0,顯然1左邊小於等於它的沒有
Add(1,1)
1 0 1 1 1
Sum(1)=1,顯然1左邊小於等於它的有一個
Add(1,1)
2 0 1 1 1
Sum(2)=2,顯然2左邊小於等於它的有2個
求右邊類似
C數組
1位置 2位置 3位置 4位置 5位置
0 0 0 0 0
Sum(2)=0;
Add(2,1)
0 1 0 0 0
Sum(1)=0
Add(1,1)
1 1 0 0 0
Sum(1)=1
Add(1,1)
2 1 0 0 0
····