Subway Lines(樹上兩條路的交點數)

2021-08-30 06:39:53 字數 1975 閱讀 9627

原題:

題意:給出一棵樹,n節點,每次詢問給兩對葉子,求這兩對葉子產生路徑的交集

解析:

找被走過兩次的點->走被走過兩次的所有lca,lca所構成的那一段長度就是點的數量

顯然,目標線段的端點一定是這些葉子節點的某個lca

找到所有lca,放入set

統計哪些lca被走過兩次

怎麼判斷走過幾次:一對葉子(x1,x2)與它的節點l1,假設某個點在x1到l1之間或x2到l2之間,則在路徑上

怎麼判斷在x1和l1之間:lca(x1,p)==p&&lca(p,l1)==l1對於走過兩次的點,求出組成路徑的長度

怎麼求路徑:首先是所有點的lca,作為root,刪除除了最底下點以外的所有點

怎麼刪除:if(lca(p1,p2)==p2)erase(p2)

#include

using namespace std;

#define maxn 500005

int head[maxn<<1]

,fa[maxn][25

],vis[maxn]

,cnt,dep[maxn]

,dis[maxn]

;struct node

e[maxn<<1]

;void

add(

int x,

int y)

void

bfs()}

}int

lca(

int x,

int y)

set<

int>st;

map<

int,

int>mp;

vector<

int>fin;

intmain()

for(set<

int>

::iterator it=st.

begin()

;it!=st.

end(

);it++

)int ans=0;

for(map<

int,

int>

::iterator it=mp.

begin()

;it!=mp.

end(

);it++)if

(fin.

size()

==0)if

(fin.

size()

==1)int l3,deep=

1e9;

for(

int i=

0;isize()

;i++

)while

(fin.

size()

>2)

}}if(

lca(fin[0]

,fin[1]

)==fin[0]

) fin.

erase

(fin.

begin()

);elseif(

lca(fin[0]

,fin[1]

)==fin[1]

) fin.

erase

(fin.

begin()

+1);

for(

int i=

0;isize()

;i++

) ans+

=(dep[fin[i]

]-dep[l3]);

ans++

;printf

("%d\n"

,ans);}

return0;

}

一條分兩條

一條拆成兩條 統計當前客戶經理和客戶關係,上年底客戶經理和客戶關係 如果客戶經理和客戶關係跨越這兩個時間段,那麼一條分成兩條 with basic t as 客戶和客戶經理關係表 select 123 cust no,a am no,20091231 start dt 29991231 end dt...

兩條序列聯配

一 序列聯配的概念 序列聯配又叫序列比對,根據特定的計分規則,通過演算法對多條蛋白質序列或dna序列進行比對,找出最優匹配和最大相似度匹配。通過聯配可以得到乙個相似度比對值 根據計分規則算 這個值反映了他們的相似度 同源性 進化上的親緣關係。序列聯配分為區域性聯配和全域性聯配兩種。全域性聯配就是對整...

牛客 兩條斜線

題意 斜率為 1的兩條直線最多經過幾個點。題解 設斜率為1的直線為y x b1,斜率為 1的直線為y x b2,b1 y x,b2 y x,b1或b2相同則點在這兩條直線上。所以問題變成了最多有幾個點的b1或b2相同,那麼列舉b1b2即可。include using namespace std ma...