隨便口胡,錯誤一大堆,歡迎打臉
d1t2因為只有n條邊,所以只存在簡單環,那我們把這個問題複雜一下,每個人可能能告訴多個人,也就是邊的數量大於n,那麼這樣的話就會出現複雜環了。如果還是直接用tarjan求的話肯定是錯的,因為tarjan每次找的是一整個大環。在這裡想到了一種比較簡單的解法。
我們每次選乙個沒有走過的點開始dfs,並一路將走到的點壓入存路徑的棧中,同時用visit[i]表示i有沒有走過,設當前的路徑是p,
visited[i]=0 …………i從未被訪問過 精確的說是i可以訪問
visited[i]=1 …………i已經被訪問過 且i在p中
visited[i]=2 …………i已經被訪問過 且i不在p中
對於所有visited[i]=2的點我們就沒有必要訪問了,說明:設當前點是now,下乙個是next且visited[next]=2,假設next和now在乙個環裡的話,曾經訪問next的時候就應該可以訪問到now,但是事實上並沒有訪問到,所以說明next和now不在乙個環裡,那麼這個點也就是沒有意義,就可以不必去找next了。
在dfs的時候一路給點打上時間戳,用spfa的思想,因為我們從乙個固定的點出發,小環中的邊比大環中的邊少,那麼如果乙個點同時存在於小環和大環中的話,從小環走過來的時候時間戳肯定比大環走過來小,那麼我們每次如果找到乙個點,當前的時間戳大於已有的時間戳的話,就將這個點更新,重新設為可選。
如果我們某一次訪問到乙個點k,滿足visited[k]=1,那麼p就是乙個完整的環,用p來更新答案,同時用上面spfa的思想看能否更新k點,如果能更新就繼續從k點往下走。
但是這樣遇到了乙個問題,眾所周知spfa的複雜度是o(em)的,e是不確定的常數,也就是說在上文的方法中,如果某些點不斷被更新,就很容易被卡掉,如下就是乙個例子:
(用紅點表示n/2+1號點)可以很明顯看出,答案應該是1->2->紅點->.....->n-1->n,但如果我們刻意控制一下讀入方式,導致遍歷的時候從1先到了2再到3一直到n/2號點,在n/2->紅點的時候更新了一下紅點的時間戳,於是紅點變成可訪問,花了o(n/2)的時間把剩下的點遍歷了一遍,回來以後到n/2-1的時候又更新了一下紅點,又花了o(n/2)的時間,這樣一直下去,總共紅點被更新了n/2次,那麼這樣的實際複雜度已經達到了o(n^2/4)的時間,在n=200000的時候是遠遠超過了限制。
我們的目的就是,優化,再優化!
對於這個問題,一種比較好的方法是a*或者估價函式,但如果是在考場上的話,隨機化也不失為一種高效而簡潔的方法。我們對於每個點,將連出去的邊的順序隨機打亂然後再依次訪問,對於上文的情況,如果一路下去一直訪問到n/2的情況的可能性只有,考慮極限情況就是nlogn的複雜度,也就是運氣很差的情況下,一直訪問到logn號點,直到此時才開始更新,那麼這樣的概率是,也就是,n越大,超時的可能性反而越小,只有十萬分之一,是在可接受範圍內的。
但是如果rp**,真的遇到這樣的情況怎麼辦呢?
再優化!
可以發現,每次找到紅點的時候,接下來的一段都是重複走的,一條鏈和一條邊實際上是乙個效果,所以我們考慮將每個單鏈都縮成一條邊,如果再像上圖那種情況的話,紅點和1之間的鏈縮成一條邊,複雜度直接降了乙個o(n),總複雜度最壞也只有o(n),至此,這題的複雜度仍然是o(em),但是e已經降成了乙個很小的常數了。
不過還不夠,我們還有更好的優化!
之前的visited[i]=2,說明i是乙個不用訪問的點,但事實上,我們還是列舉了i,對常數還是造成了一點影響,所以我們考慮可不可以讓列舉的每個點都是有意義的點。
最終的結果是要找最小環,既然是個環,那我們就在環裡找環,不在環裡的點就直接拋棄掉。所以我們先做一遍tarjan,將所有的大環提取出來,然後再從每個環裡按上文方法進行遍歷,這樣的話找最小環的複雜度就趨於穩定了。
總複雜度:o(n+m+km),常數k在最壞情況下為10左右。
至此,這道題就基本解決了,是否還有更穩定更快的方法,仍然會繼續**。
隨便口胡,錯誤一大堆,歡迎打臉
暑假 D1 T2 咖啡的藝術
掃瞄線 事件點 0集合 描述了每一種咖啡的溫度區間 l,r l 1 r 1 1 1集合 描述了每乙個查詢區間 l,r l i r 1 i top記錄n集合的差分字首和 now記錄q集合的差分字首和。構造好事件點後按l r 排一遍序 按順序往後掃。if cnt1 k ans 區間長度 i includ...
NOIP 2015 D1 T2 資訊傳遞
問題描述 有n個同學 編號為1到n 正在玩乙個資訊傳遞的遊戲。在遊戲裡每人都有乙個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件 注意 可能有人可以從若干人那裡獲取資...
NOIP2015 D1T2 資訊傳遞
一道有很多種解法的題目 通過劃歸,發現就是求最小環 那麼立即能想到的演算法 1 tarjan求強連通分量,最無腦 2 對於每個連通分量用topo sort,相當於剪去其他不在環上的邊 不過用帶權並查集也可以解決這道題目 首先發現只要一條邊連線的兩個點a b在之前已經在乙個集合中,則必定會形成乙個環 ...