HDU 4547 CD操作 (離線Tarjan)

2021-10-01 01:40:40 字數 1595 閱讀 1650

在windows下我們可以通過cmd執行dos的部分功能,其中cd是一條很有意思的命令,通過cd操作,我們可以改變當前目錄。 

這裡我們簡化一下問題,假設只有乙個根目錄,cd操作也只有兩種方式: 

1. cd 當前目錄名\...\目標目錄名 (中間可以包含若干目錄,保證目標目錄通過絕對路徑可達) 

2. cd .. (返回當前目錄的上級目錄) 

現在給出當前目錄和乙個目標目錄,請問最少需要幾次cd操作才能將當前目錄變成目標目錄?

input

輸入資料第一行包含乙個整數t(t<=20),表示樣例個數; 

每個樣例首先一行是兩個整數n和m(1<=n,m<=100000),表示有n個目錄和m個詢問; 

接下來n-1行每行兩個目錄名a b(目錄名是只含有數字或字母,長度小於40的字串),表示a的父目錄是b。 

最後m行每行兩個目錄名a b,表示詢問將當前目錄從a變成b最少要多少次cd操作。 

資料保證合法,一定存在乙個根目錄,每個目錄都能從根目錄訪問到。

output

請輸出每次詢問的結果,每個查詢的輸出佔一行。

sample input

2

3 1b a

c ab c

3 2b a

c ba c

c a

sample output

2

12

題目大意:一共有三種情況:1.u是v的祖先1次就到, 2.v是u的祖先 v到u的距離,3.否則u到公共祖先的距離+1

**:

#include#include#include#include#includeusing namespace std;

#define mem(a,b) memset(a,b,sizeof(a))

const int n=100000+20;

int first[n],first1[n],fa[n],d[n],vis[n],vis1[n],isroot[n],ans[n];

int tot,tott,root,n,m;

mapmp;

struct node

e[n<<1];

struct query

q[n<<1];

struct poi

qq[n<<1];

void adde(int u,int v)

void addee(int u,int v,int id,int flag)

void init()

int find(int x)

void dfs(int u,int len)

}void lca(int u,int pre)

vis[u]=1;

for(int i=first1[u];~i;i=q[i].next)

}}int main()

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

if(!isroot[i])

dfs(root,0);

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

lca(root,root);

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

}return 0;

}

HDU 4547 CD操作 LCA倍增

題目傳送門 hdu 4547 cd操作 略求出目錄a 到 b所需要的cd操作次數,這裡的a b 位字串 所以用到map對映,之後直接求lca分情況討論即可 設求a到b的cd運算元 1 a b 需要的cd運算元是0 2 a是b的最近公共祖先,則a b的cd運算元是0 3 b是a的最近公共祖先,則b a...

BZOJ4547 Hdu5171 小奇的集合

給有乙個大小為n的可重集s,每次操作可以加入乙個數a b a,b均屬於s 求k次操作後它可獲得的s的和的最大 值。資料保證這個值為非負數 我們先來看看,因為我們要得到最大的s,所以每次我們都要使得a b最大 首先排除一開始得到的a,b為負數的情況,我們將a b放進s裡,那麼下一次操作就會將a a b...

hdu2045 c語言詳解

因為格仔數為1,2,3時為特殊情況,所以從4開始考慮,分為兩種情況,第一種情況 當第n 1個格仔與第乙個格仔不同時,因為題目要求第乙個格仔和最後乙個不相同,所以此時巧好能看成總共只有n 1個格仔,然後又回到有n格仔時,第n個格仔因為不和第乙個和第n 1個格仔相同,當第n 1個格仔和第乙個格仔確定時,...