在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
2sample output3 1b a
c ab c
3 2b a
c ba c
c a
2題目大意:一共有三種情況:1.u是v的祖先1次就到, 2.v是u的祖先 v到u的距離,3.否則u到公共祖先的距離+112
**:
#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個格仔和第乙個格仔確定時,...