題意:給出一棵樹,求樹上最長距離(直徑),以及這樣的距離的條數。
思路:如果只求直徑,用兩次dfs即可。但是現在要求最長距離的條數,用dp1[u]記錄以u為根的子樹中葉子結點到u的最長距離,dp2[u]表示最長距離的條數,這兩個比較容易維護。dfs過程中更新答案,用ans1表示樹上直徑,ans2表示該直徑的條數,當dp1[v]+w+dp1[u]>ans1時更新。
ac**:
#include#include順便附上只用兩次dfs求直徑的**:using
namespace
std;
const
int maxn=1e4+5
;typedef
long
long
ll;int
n,cnt,head[maxn];
ll ans1,ans2,dp1[maxn],dp2[maxn];
struct
nodeedge[maxn
<<1
];void adde(int u,int v,int
w)void dfs(int u,int
fa)
else
if(tmp+dp1[u]==ans1)
if(tmp>dp1[u])
else
if(tmp==dp1[u])
}}int
main()
dfs(
1,0);
printf(
"%lld %lld\n
",ans1,ans2);
}return0;
}
#include#includeview code#include
using
namespace
std;
typedef
long
long
ll;const
int maxn=1e4+5
;int
n,cnt,head[maxn];
ll dp1[maxn],dp2[maxn];
struct
nodeedge[maxn
<<1
];void adde(int u,int v,int
w)void dfs(int u,int
fa) }
if(!flag) dp2[u]=u;
}int
main()
dfs(
1,0);
int tmp=dp2[1
]; dfs(tmp,0);
printf(
"%lld\n
",dp1[tmp]);
}return0;
}
樹形dp 求樹的直徑
隨著杭州西湖的知名度的進一步提公升,園林規劃專家湫湫希望設計出一條新的經典觀光線路,根據老闆馬小騰的指示,新的風景線最好能建成環形,如果沒有條件建成環形,那就建的越長越好。現在已經勘探確定了n個位置可以用來建設,在它們之間也勘探確定了m條可以設計的路線以及他們的長度。請問是否能夠建成環形的風景線?如...
hdoj2196(樹形dp,樹的直徑)
題意 給出一棵樹,求每個結點可以到達的最遠距離。思路 如果求得是樹上最長距離,兩次bfs就行。但這裡求的是所有點的最遠距離,樹形dp的經典題,想了乙個小時,還是dp做得太少。分析可得對任意結點u,它的最長距離要麼是向下延伸的最長距離,要不向上延伸的最長距離。我們用dp u 0 表示節點u向下 子結點...
DP 樹形 DP 樹的中心
做法 a 大致想法是進行兩遍dfs,找到每個節點的向下的最長路徑 di 和向上的最長路徑 ui 然後列舉每乙個點,再找到min max di ui b 補充細節 1 根據樹的直徑求法,向下求的時候會有乙個最大值和次大值,例如節點 i 的 d1i d2i,當更新 i 的某個子節點 j 的 uj 時候,...