小機房的樹codevs 2370
————最近公共祖先和動態規劃的完美結合
【題目描述】
小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n-1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花費 c 的能量(從父親節點爬到此節點也相同),他們想找出一條花費精力最短的路,以使得搞基的時候精力旺盛,他們找到你要你設計乙個程式來找到這條路,要求你告訴他們最少需要花費多少精力。
【輸入描述】
第一行乙個n,接下來n-1行每一行有三個整數u,v, c 。表示節點 u 爬到節點 v 需要花費 c 的精力。
接下來m行每一行有兩個整數 u ,v 表示兩隻蟲子所在的節點
【輸出描述】
一共有m行,每一行乙個整數,表示對於該次詢問所得出的最短距離
【分析】
求樹上最短路,而且要求的是nlogn的演算法,很容易能想到lca,確實,lca的確適合樹上最短路
ps:lca的具體內容博主的部落格裡有
求出兩點的lca的過程中即可計算答案,我們設d(i,j)表示樹上的i節點向上走2^j到達的節點所走的距離
而d陣列在初始化深度的時候即可計算
時間複雜度o(nlogn)
完美ac...
【**】
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;67
const
int maxn=100001;8
9struct
liste[maxn];
1213
int head[maxn],n,cnt=0;14
int deep[maxn],p[maxn][22],d[maxn][22];//
d(i,j)表示i到第2^j祖先的距離
15int ans=0;16
17void addedge(int u,int v,int
w)24
25int lca(int u,int
v)33
for(i=21;i>=0;i--)
34if(p[u][i]!=p[v][i])
39if(u!=v)ans+=d[u][0]+d[v][0
];40
return
ans;41}
4243
void dfs(int
u)50
for(i=head[u];i;i=e[i].next)
51if(!deep[e[i].to])57}
5859
intmain()
67 u=1;68
for(i=0;i)
69if(!deep[i])
74 scanf("
%d",&c);
75while(c--)
80return0;
81 }
無可否認,lca的**是有點長,但理解了還是很容易能敲出來的
Codevs 2370 小機房的樹
2370 小機房的樹 時間限制 1 s 空間限制 256000 kb 題目等級 鑽石 diamond 傳送門題目描述 description 小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩...
CODEVS 2370小機房的樹
題目描述description 小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花費 c 的能量 從父親節點爬到此節點也相同 他們...
CODEVS 2370 小機房的樹
題目描述 description 小機房有棵煥狗種的樹,樹上有n個節點,節點標號為0到n 1,有兩隻蟲子名叫飄狗和大吉狗,分居在兩個不同的節點上。有一天,他們想爬到乙個節點上去搞基,但是作為兩隻蟲子,他們不想花費太多精力。已知從某個節點爬到其父親節點要花費 c 的能量 從父親節點爬到此節點也相同 他...