hdu 4912 貪心 最近公共祖先

2021-06-28 10:37:12 字數 1446 閱讀 7446

先對所有的路徑求取lca,然後按照lca從大到小的順序選取路徑

若一條路徑p1的lca(p1) 的深度大於p2的lca(p2),那麼若p1和p2出現衝突,那麼p1一定包含p2的lca(p2),那麼p2只可能與以lca(p2)為子樹中的路徑衝突,而p1要衝突的範圍更大,兩個的貢獻同樣是1,如果存在一棵比lca(p1)和lca(p2)深度都大的子樹中的子樹中路徑,如果它和p1不衝突,卻和p2衝突,那麼它已經將p2淘汰,但不會影響p1的選取,所以當前貪心策略是正確的.

#include #include #include #include #define max 200007

using namespace std;

int ce , cq;

struct edge

e[max<<1];

struct query

}q[max<<1];

int head1[max];

int head2[max];

int depth[max];

void adde ( int u , int v )

void addq ( int u , int v )

int fa[max];

int find ( int x )

void lca ( int u = 1 , int p = -1 )

for ( int i = head2[u] ; i != -1 ; i = q[i].next )

} bool vis[max];

int pa[max];

void dfs ( int u = 1 , int p = -1 , int deep = 1 )

}void paint ( int i , int u )

bool judge ( int i , int u )

u = q[i].v;

while ( u != lca )

if ( vis[lca] ) return false;

return true;

}int main ( )

for ( int i = 0 ; i < m ; i++ )

dfs ();

lca ();

sort ( q , q+2*m );

int ans = 0;

// for ( int i = 1 ; i <= n ; i++ )

// cout << i <<" : " << pa[i] << endl;

for ( int i = 0 ; i < cq ; i++ )

// for ( int i = 1 ; i <= n ; i ++ )

// cout << vis[u] << " ";

// cout << endl;

}printf ( "%d\n" , ans );

}}

hdu 4912 終於解脫了

歷經n發wa之後 終於解脫了 這感覺.無法言表.其實 這題你說難吧?對於我而言 一共就做過一道lca的人來說 是有點難的 可是吧 當你慢慢地寫下來 其實 那麼長 又不怎麼難 對於此題 就是先求出query中2個結點的lca之後 然後dfs它們的lca 根據深度進行排序 這個其實不難理解吧?當然深度越...

最近公共祖先 python 最近公共祖先

lca演算法樸素演算法 也就是我們所說的暴力演算法,大致的思路是從樹根開始,往下迭代,如果當前結點比兩個結點都小,那麼說明要從樹的右子樹中找 相反則從左子樹中查詢 直到找到乙個結點在當前結點的左邊,乙個在右邊,說明當前結點為最近公共祖先,如果乙個結點是另外乙個結點的祖先,那麼返回前面結點的父親結點即...

最近公共祖先 LCA 最近公共祖先

直接暴力搜尋參考 普通搜尋每次查詢都需要 樸素演算法是一層一層往上找,倍增的話直接預處理出乙個 具體做法是 維護乙個 的關係來線性求出這個陣列 int anc n 31 int dep n 記錄節點深度 void dfs int u,int parent for int i 0 i g u size...