題目描述有n只猴子,第一只尾巴掛在樹上,剩下的n-1只,要麼被其他的猴子抓住,要麼抓住了其他的猴子,要麼兩者均有。當然乙隻猴子最多抓兩隻另外的猴子。現在給出這n只猴子抓與被抓的資訊,並且在某個時刻可能某只猴子會放掉它其中乙隻手的猴子,導致某些猴子落地。求每只猴子落地的時間。
輸入輸出格式
輸入格式:
第一行兩個數n、m,表示有n只猴子,並且總時間為m-1。接下來n行,描述了每只猴子的資訊,每行兩個數,分別表示這只猴子左手和右手抓的猴子的編號,如果是-1,表示該猴子那只手沒抓其他猴子。再接下來m行,按時間順序給出了一些猴子放手的資訊,第1+n+i行表示第i-1時刻某只猴子的放手資訊,資訊以兩個數給出,前者表示放手的猴子編號,後者表示其放的是哪隻手,1左2右。
【資料規模】
30%的資料,n≤1000,m≤1000;
100%的資料,1≤n≤200000,1≤m≤400000。
輸出格式:
共輸出n行,第i行表示第i只猴子掉落的時刻,若第i只猴子島m-1時刻以後還沒掉落,就輸出-1。
輸入輸出樣例
輸入樣例#1:
3 2-1 3
3 -1
1 21 2
3 1輸出樣例#1:-11
1
首先看到這道題的時候想到的是暴力,或者是模擬,但是我不會
之後開始我們的正文,這是我近來學習並查集的最後乙個內容,倒序並查集
因為沒有思路,所以我看了題解+問了石神才把這道題搞懂了,但是這道題並不是說不再處理了,而是之後要強加聯絡。
解題報告:
簡化題面:對於這道題而言可以看成是斷開以後的若干個連通塊的問題,若是當前的連通塊中有1號節點,那麼這個連通塊就始終不會掉落,反之,其他的連通塊是一定會掉落的。
理清演算法:對於若干個連通塊的問題的合併,查詢,斷開,我們首先考慮的當然是並查集,但是,這樣的話,就又有了乙個麻煩事兒,並查集怎麼斷開??
既然不會,就換個思路,我們倒著做並查集,我們可以倒著加邊。原來的正著刪邊的結束條件是什麼時候與1號節點斷開連線,那麼倒著加邊的演算法的結束條件就是什麼時候與1號節點建上聯絡。
思路總結:我們首先要進行n個前提的記錄,之後是要有m個斷開條件的標記,最後是並查集的處理,倒序加邊。
寫這道題的時候存在的一些問題:
q:為什麼最後要倒序處理?
a:因為正序的搞的並查集的斷開,很難,所謂我們此時應該換乙個思路。我們倒序,變成是並查集的加邊,把斷開的時間轉化成是連上第乙個節點的時間
q:為什麼這道題可以用並查集做?
a:因為這道題可以看成是若干個連通塊的問題,如果有點始終存在於1號的連通塊內,那麼就始終不會掉落,那麼其他的會掉落的連通塊就是看根節點的最早的掉落時間即是整個連通塊的掉落時間。若干個連通塊的問題的連線和合併(或者是斷開)就可以用並查集問題。
但是此時並查集的斷開需要更加高深的知識(我不會),所以我們就可以倒序處理這m條關係,換成是加邊。
末狀態倒推初狀態,判斷最後連線到第一只猴子的時間就是這一坨猴子掉下的時間。
對於各個點都用並查集維護,它掉落的時間由他的所有的祖先中鬆手最早的那乙隻猴子決定。
#include
using
namespace std;
const
int nn=
200010
;const
int mm=
400010
;int n,m;
int fa[nn]
,ans[nn]
;int son[nn][3
],bj[3]
[nn]
;struct monkey
k[mm]
;inline
intread()
while
(ch>=
'0'&&ch<=
'9')
return x*f;
}intgf(
int x)
void
union
(int x,
int y,
int z)
else}}
intmain()
for(
int i=
1;i<=m;
++i)
for(
int i=
1;i<=n;
++i)
for(
int i=m;i>=1;
--i)
/*記得倒序操作,轉化成是加邊處理*/
if(son[k[i]
.id]
[k[i]
.l]!=-1
)/*m條資訊,這樣的話就要為m條資訊編上時間,是自己程式性死亡的初始時間*/
union
(k[i]
.id,son[k[i]
.id]
[k[i]
.l],i-1)
;/*判斷這兩個點什麼時候連上邊(相互脫離)*/
printf
("%d\n",-
1);/*1號節點是一定不會被移除的節點,可以直接輸出-1*/
for(
int i=
2;i<=n;
++i)
return0;
}
**之中是有一些細節的。
問題:在原**中,有乙個操作是把所有的與1聯通的點的答案全部賦值為1e9,但是我發現這個操作可以完全不必要,因為在這個操作之前,完全沒有修改ans的操作。
注意注意,在gf函式中應該是有兩個return的,不要忘打了乙個,這樣的話就會一直跑下去,然後,你的程式就掛掉了!!
一直努力著,適應著這個世界的溫度,不管是季節還是人心。
黑猴子的家 Spark RDD 為什麼會產生
rdd是spark的基石,是實現spark資料處理的核心抽象。hadoop的mapreduce是一種基於資料集的工作模式,面向資料,這種工作模式一般是從儲存上載入資料集,然後運算元據集,最後寫入物理儲存裝置。資料更多面臨的是一次性處理。mr的這種方式對資料領域兩種常見的操作不是很高效。第一種是迭代式...
可愛的猴子
可愛的猴子 時間限制 10000 ms 空間限制 65536 kb 問題描述 樹上有n只猴子。它們編號為 1 到n。1 號猴子用它的尾巴勾著樹枝。剩下的猴子都被其他的猴子用手抓著。每只猴子的每隻手可以抓住另乙隻猴子的尾巴。從0 時刻開始,每一秒都有乙隻猴子鬆開它的乙隻手。這會導致一些猴子掉到地上 它...
可愛的猴子
可愛的猴子 時間限制 10000 ms 空間限制 65536 kb 問題描述 樹上有n只猴子。它們編號為 1 到n。1 號猴子用它的尾巴勾著樹枝。剩下的猴子都被其他的猴子用手抓著。每只猴子的每隻手可以抓住另乙隻猴子的尾巴。從0 時刻開始,每一秒都有乙隻猴子鬆開它的乙隻手。這會導致一些猴子掉到地上 它...