0.總結
get to the points first. the article comes from lawsonabs!
1.問題
在談lca之前,說一下什麼是二進位制拆分
1.1 二進位制拆分
我們都知道,計算機中的數都是用0/1來表示的,也就是說任何乙個正整數都可以用二進位制來表示出來,但是小數卻是不行的。用二進位制來表示任何乙個正整數的思想就叫做二進位制拆分。
1.2 lca問題
2.分析
3.**
3.1 **
#include
#include
#include
#include
using namespace std;
const
int maxn =
500005
;//最大結點數
const
int maxm =
1000010
;//因為是無向邊 ,所以要*2
const
int maxd =25;
//最深
typedef
struct
edge ;
typedef
struct
node;
queue que;
edge edge[maxm]
;//邊長
int f[maxn]
[maxd]
;//f[i][j] 表示節點i向上走2^j步所能到達的節點的序號 ;
//如果f[i][j]=0,則表示 從i節點向上走2^j步,沒有父節點
int hei[maxn]
,vis[maxn]
,head[maxn]
;//深搜知道各個節點的深度;該頂點是否訪問過;每個頂點的頭指標
int en;
//邊數
int n,m,s,k;
//k = log2(n)
void
add(
int a,
int b)
//預處理f
void
bfs())
;int topid,deep;
//隊首;隊尾
int eto;
//相鄰的點
while
(!que.
empty()
)}for(
int i = head[topid]
; i!=-1
; i=edge[i]
.next)
que.
push
((node));
//放進佇列
f[eto][0
]= topid;
//這是很重要的一步 ,不能疏漏了 }}
}void
lca(
int x,
int y)
}//step2. 深度相同時,情況1:二者已經相同了,此時就是lca
if(x == y)
//step3.深度相同時:情況2:可能只是同一層,但lca還在高處,走多少步還是不知道的,
//所以還是需要從大往小走
else
}//最後還得走一步
printf
("%d\n"
,f[x][0
]);}
}int
main()
bfs();
//驗證輸出f函式是否搞對了
// for(int i = 1;i<=n;i++)cout <<"\n";
// }
for(
int i =
0;i)}
3.2 測試用例:9 5 1
1 21 3
2 42 5
5 93 6
3 76 8
1 11 2
2 86 7
8 73 3 1
1 22 3
1 21 3
2 3
4.相關例題 演算法競賽刷題模板2 歸併排序
get to the points first.the article comes from lawsonabs update on 20200622 在給出真正可執行的 之前,我想給出乙個偽 畢竟偽 更好理解和記憶。const int maxn 100005 int arr maxn int su...
演算法競賽刷題模板14 大整數乘法
0.總結 get to the points first.the article comes from lawsonabs 本文不適合零基礎選手 1.要求 實現大整數乘法。2.實現 主要思想 include include using namespace std const int maxm 105...
PAT刷題模板 最短路徑演算法
dijkstral演算法適用於無負權邊的圖。圖結構和輔助陣列 const int inf 0x3fffffff inf定義為了int的上限 cost為邊權矩陣 weight為點權,若有則可以使用 int g maxn maxn cost maxn maxn weight maxn weight ca...