tarjan---lca演算法的步驟是(當dfs到節點u時):
實際: 並查集+dfs
具體步驟:
1 在並查集中建立僅有u的集合,設定該集合的祖先為u
1 對u的每個孩子v:
1.1 tarjan之
1.2 合併v到父節點u的集合,確保集合的祖先是u
2 設定u為已遍歷
3 處理關於u的查詢,若查詢(u,v)中的v已遍歷過,則lca(u,v)=v所在的集合的祖先。
舉例子:
假設遍歷完10的孩子,要處理關於10的請求了
取根節點到當前正在遍歷的節點的路徑為關鍵路徑,即1-3-8-10
集合的祖先便是關鍵路徑上距離集合最近的點
比如此時:
1,2,5,6為乙個集合,祖先為1,集合中點和10的lca為1
3,7為乙個集合,祖先為3,集合中點和10的lca為3
8,9,11為乙個集合,祖先為8,集合中點和10的lca為8
10,12為乙個集合,祖先為10,集合中點和10的lca為10
你看,集合的祖先便是lca吧,所以第3步是正確的
道理很簡單,lca(u,v)便是根至u的路徑上到節點v最近的點
此段話語來自sre="
"模板:
1 #include2 #include3using
namespace
std;45
const
int max=10001;6
intfather[max];
7int
rank[max];
8int indegree[max];//
儲存每個節點的入度
9int
visit[max];
10 vectortree[max],qes[max];
11int
ancestor[max];
1213
14void init(int
n)15
2728}29
30int find(int
n)31
//查詢函式,並壓縮路徑
3839
int union(int x,int
y)40
51else
5256
return1;
5758 }//
合併函式,如果屬於同一分支則返回0,成功合併返回1
5960
61void lca(int
u)62
71 visit[u]=1
;72 size =qes[u].size();
73for(int i=0;i)
7481}82
}838485
intmain()
86101
//這裡可以輸入多組詢問
102 cin>>s>>t;
103//
相當於詢問兩次
104qes[s].push_back(t);
105qes[t].push_back(s);
106for(int i=1;i<=n;i++)
107114
}115
}116
return0;
117 }
tarjan lca最小公共祖先演算法
另一篇比較清楚的文章 原文 1,並查集 dfs 對整個樹進行深度優先遍歷,並在遍歷的過程中不斷地把一些目前可能查詢到的並且結果相同的節點用並查集合並.2,分類,使每個結點都落到某個類中,到時候只要執行集合查詢,就可以知道結點的lca了。對於乙個結點u.類別有 以u為根的子樹 除類一以外的以f u 為...
關於Java nofity wait的個人理解
首先notify,wait的經典場景是生產者,消費者模型 importorg.slf4j.logger created by wcl on 17 9 17.public classconsumerimplementsrunnable public voidrun 消費 1,當前數量 name,con...
cookie和session的個人簡單理解
瀏覽器 客戶端發起請求 伺服器響應 setcookie要求瀏覽器 客戶端生成乙個cookie 瀏覽器 客戶端儲存cookie,並在下次請求中在請求頭中傳送這個cookie 伺服器識別這個瀏覽器發來的cookie,證明是同一使用者 這個使用者請求相同的伺服器都會傳送這一cookie重複3 5步,伺服器...