並查集求最近公共祖先
package algorithm;
import java.io.BufferedOutputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
class UnionFind{
int MAX = 17;
int father[] = new int[MAX];
int rank[] = new int[MAX];
int indegree[] = new int[MAX];
int visited[] = new int[MAX];
HashMap<Integer, ArrayList<Integer>> tree,query;
int ancestor[] = new int[MAX];
PrintWriter writer;
void init(int n){
for(int i = 1; i <= n; i++){
father[i] = i;
rank[i] = 1 ;
indegree[i] = 0;
visited[i] = 0;
ancestor[i] = 0;
}
try {
writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream("C:\\a.txt")),true);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
int Find_Set1(int x){
if(x != father[x])
father[x] = Find_Set(father[x]);
return father[x];
}
int Find_Set(int x){
if(x == father[x])
return x;
else
father[x] = Find_Set(father[x]);
return father[x];
}
int Union(int x, int y){
int a = Find_Set(x);
int b = Find_Set(y);
if(a == b)
return 0;
if(rank[a] >= rank[b]){
father[b] = a;
writer.println("father["+b+"]="+a);
rank[a] += rank[b];
}else{
father[a] = b;
writer.println("father["+a+"]="+b);
rank[b] += rank[a];
}
return 1;
}
void LCA1(int u){
ancestor[u] = u;
if(tree.get(u) != null)
for(int unode : tree.get(u)){
LCA(unode);
Union(u, unode);
ancestor[Find_Set(u)] = u;
}
visited[u] = 1;
if(query.get(u) != null)
for(int vnode : query.get(u)){
if(visited[vnode] == 1)
System.out.println(u + "和" + vnode +"的最近公共祖先為 :" + ancestor[Find_Set(vnode)]);
}
}
void LCA(int u){
//System.out.println("u進入 u= "+u);
writer.println("u進入 u= "+u);
ancestor[u] = u;
//System.out.println("ancestor["+u+"]="+u);
writer.println("ancestor["+u+"]="+u);
if(tree.get(u) != null){
ArrayList<Integer> ulist = tree.get(u);
for(int unode : ulist){
LCA(unode);
// System.out.println("return ");
// System.out.println("合併 "+u +"和"+unode);
writer.println("return " );
writer.println("合併 "+u +"和"+unode);
Union(u, unode);
ancestor[Find_Set(u)] = u;
// System.out.println("Find_Set("+u+")="+Find_Set(u));
// System.out.println("ancestor["+u+"]="+Find_Set(u));
writer.println("Find_Set("+u+")="+Find_Set(u));
writer.println("ancestor["+Find_Set(u)+"]="+u);
}
}
visited[u] = 1;
// System.out.println(u+" 訪問標誌置1");
writer.println(u+" 訪問標誌置1");
if(query.get(u) != null){
writer.println("query "+u+" 不為空");
ArrayList<Integer> vlist = query.get(u);
for(int vnode : vlist){
if(visited[vnode] == 1){
System.out.println(u + " 和 " + vnode +" 的最近公共祖先為 :" + ancestor[Find_Set(vnode)]);
writer.println(u + " 和 " + vnode +" 的最近公共祖先為 :" + ancestor[Find_Set(vnode)]);}
}
}
}
void commonAncestor(int x, int y){
int n = 16;
init(n);
tree = new HashMap<Integer, ArrayList<Integer>>();
query = new HashMap<Integer, ArrayList<Integer>>();
ArrayList<Integer> list1 = new ArrayList<Integer>();
list1.add(5); indegree[5]++;
list1.add(4);indegree[4]++;
list1.add(1);indegree[1]++;
tree.put(8, list1);
ArrayList<Integer> list2 = new ArrayList<Integer>();
list2.add(9);indegree[9]++;
tree.put(5, list2);
ArrayList<Integer> list3 = new ArrayList<Integer>();
list3.add(6);indegree[6]++;
list3.add(10);indegree[10]++;
tree.put(4, list3);
ArrayList<Integer> list4 = new ArrayList<Integer>();
list4.add(14);indegree[14]++;
list4.add(13);indegree[13]++;
tree.put(1, list4);
ArrayList<Integer> list5 = new ArrayList<Integer>();
list5.add(15);indegree[15]++;
list5.add(7);indegree[7]++;
tree.put(6, list5);
ArrayList<Integer> list6 = new ArrayList<Integer>();
list6.add(11);indegree[11]++;
list6.add(16);indegree[16]++;
list6.add(2);indegree[2]++;
tree.put(10, list6);
ArrayList<Integer> list7 = new ArrayList<Integer>();
list7.add(3);indegree[3]++;
list7.add(12);indegree[12]++;
tree.put(16, list7);
ArrayList<Integer> q = new ArrayList<Integer>();
q.add(x);
ArrayList<Integer> q2 = new ArrayList<Integer>();
q2.add(y);
query.put(x, q2);
query.put(y, q);
LCA(8);
/*System.out.println(uf.tree);
System.out.println(uf.query);
System.out.println(uf.indegree);
for(int i = 0; i < indegree.length; i++)
System.out.print(indegree[i] + " ");
*/
/*for(int i = 1; i <= n; i++){
if(indegree[i] == 0){
uf.LCA(i);
break;
}
}*/
}
}
//並查集 + DFS 求最近公共祖先
public class UnionFind1 {
public static void main(String[] a){
UnionFind uf = new UnionFind();
uf.commonAncestor(9, 7);
}
}
相關推薦
並查集求最近公共祖先
package algorithm; import java.io.BufferedOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; imp
tarjan算法求最近公共祖先
技巧 splay 路徑壓縮 tor 沒有 blog 分析 father mar tarjian算法 LCA: LCA(Least Common Ancestor),顧名思義,是指在一棵樹中,距離兩個點最近的兩者的公共節點。也就是說,在兩個點通往根的道路上,肯定會有公共的節
Codeforces 278C Learning Languages(並查集) 求連通塊
pre union get code fin const turn find ons Codeforces 278C Learning Languages(並查集) 求連通塊 為什麽最後還要getfather 一遍 比如 x 是 y 的父親 然後你 Union(x,
HDU 3018 Ant Trip (並查集求連通塊數+歐拉回路)
http 道路 遇到 連通塊 ems ble define ant trip 註意 題目鏈接:http://acm.hdu.edu.cn/showproblem.php?pid=3018 題目大意:有n個點,m條邊,人們希望走完所有的路,且每條道路只能走一遍。至少要將人們
求最近公共祖先(LCA)的各種算法
host .cn 提取 模擬 最小值 以及 play 樹鏈剖分 pla 水一發題解。 我只是想存一下樹剖LCA的代碼...... 以洛谷上的這個模板為例:P3379 【模板】最近公共祖先(LCA) 1.樸素LCA 就像做模擬題一樣,先dfs找到基本信息:每個節點的父親、深度
HDU 1213 How Many Tables(並查集求強連通分量)
Today is Ignatius' birthday. He invites a lot of friends. Now it's dinner time. Ignatius wants to know how many tables he needs at least. You have to
hdu1232(並查集求強連通)
Problem Description 某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省政府“暢通工程”的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?  
求最近公共祖先(LCA)的三種方法總結(Tarjan/倍增/樹鏈剖分)
以模板題目poj1330為例 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below:
並查集求聯通塊個數【洛谷P1197】
傳送門:https://www.luogu.org/problemnew/show/P1197 並查集求聯通塊個數。 這個題是每摧毀一個點求一次聯通塊的個數,並查集不容易維護這種摧毀更新的,相反的,並查集可以很好的維護每安裝一個點更新一次這種問題。摧毀和安裝是對立的,既然按順序摧毀,我們就逆
Tarjan離線演算法求最近公共祖先(LCA)
轉自: arjan離線演算法求LCA介紹 前言:首先,本人搞懂Tarjan求最近公共祖先(LCA),也是瀏覽了大量其他網友大牛的文章,若是看了本文仍未弄懂的,可以嘗試自己做一下模板題(裸題)HDU2586,自己用資料去感受一下,或者可以換篇文章再看,或許他的
HDU1856(並查集求最大集合)
有比較說明一點經驗:求最大值有時候不需要把資料求出來後遍歷。 注意:最大值的求解和比較的順序沒有關係,所以可以一邊求出資料,一邊進行比較。【即用設定全域性變數maxp的方法解決】 省去最後遍歷的步驟。 #include<iostream> #include
藍橋杯歷屆試題 危險係數(dfs或者並查集求無向圖關於兩點的割點個數)
Description 抗日戰爭時期,冀中平原的地道戰曾發揮重要作用。 地道的多個站點間有通道連線,形成了龐大的網路。但也有隱患,當敵人發現了某個站點後,其它站點間可能因此會失去聯絡。 我們來定義一個危險係數DF(x,y): 對於兩個站點x和y (x != y), 如果能找到一個站點z,當
用於求最近公共祖先(LCA)的 Tarjan演算法–以POJ1986為例(轉)
給定有向無環圖(就是樹,不一定有沒有根),給定點U,V,找出點R,保證點R是U,V的公共祖先,且深度最深;或者理解為R離這兩個點的距離之和最小.如何找出R呢? 最一般的演算法是DFS(DFS本是深度優先搜尋,在這裡姑且把深度優先遍歷也叫做DFS,其實是
洛谷P2661 資訊傳遞(帶權並查集求有向圖最小環)
題目描述有n個同學(編號為1到n)正在玩一個資訊傳遞的遊戲。在遊戲裡每人都有一個固定的資訊傳遞物件,其中,編號為i的同學的資訊傳遞物件是編號為Ti同學。遊戲開始時,每人都只知道自己的生日。之後每一輪中,所有人會同時將自己當前所知的生日資訊告訴各自的資訊傳遞物件(注意:可能有人
求最近公共祖先和所有祖先
#include "btree.cpp" //二叉鏈的基本運算 #include<iostream> using namespace std; bool allAncestor(BTNo
帶權並查集求最環
/* 把每個同學看成一個點,資訊的傳遞就是在他們之間連有向邊,遊戲輪數就是求最小環。 圖論求最小環,我在裡面看到了並查集。 假如說資訊由A傳遞給B,那麼就連一條由A指向B的邊,同時更新A的父節點,A到它的父節點的路徑長也就是B到它的父節點的路徑長+1。 這樣我們就建立
一般二叉樹求最近公共祖先(最簡單的程式碼)
當遍歷到一個root點的時候, 1.判斷root是不是null如果root為null,那麼就無所謂祖先節點,直接返回null就好了 2.如果root的左子樹存在p,右子樹存在q,那麼root肯定就是最近祖先 3.如果pq都在root的左子樹,那麼就需要遞迴
並查集求集合個數和每個集合中的元素個數
思路:維護一個數組,代表以某個結點為根的樹的結點數目,初始化為全1。在合併兩個集合時,將秩較小的集合的元素數目加到秩較大的集合上。這裡需要注意一下,就是Union過程處理兩個祖先相同的結點,此時實際上沒有真正的合併這兩個結點,所以不需要更新集合的元素數目。至於統計集合個數就
3.19 Tarjan演算法與並查集解決二叉樹節點間最近公共祖先的批量查詢問題
【題目】: 如下的Node類是標準的二叉樹節點結構: 1 public class Node{ 2 public int value; 3 public Node left; 4 public Node right; 5 6 pu
最近公共祖先(並查集)
#include<stdio.h> #include<cstdlib> #include<iostream> #include<cstdio> #include<vector> #include<cstring> #include<