數的最長鏈 求最長路的思想 水題兩道

2021-08-25 05:23:16 字數 1645 閱讀 8321

求最長路的思想還是套用大佬們的分析:

給定乙個無環圖,要求途中的最長路,思想就是任意找到乙個點s,從這個點出發進行一遍dfs或者bfs,尋找到乙個離它最遠的點,可以證明這個點就是最遠點的乙個端點,再從這個點出發進行一遍dfs或者bfs,找到離他最遠的點,這兩個點的距離就是最長路.

思想還是很簡單的,只要維護乙個dist距離陣列,利用兩遍dfs就可以算出最長路了。

下面給出兩道水題,方法都是相同的,實現時有細微差別.

一.poj1985

給定乙個有向無環圖,求最長路的距離

思路:其實有向圖在求最長路dfs過程中可以當做無向圖來建邊,這樣方便進行兩次dfs尋找最遠點,且不會丟失最優解。所以此題中的方向幾乎就沒什麼用了,也是更加方便了.

#include 

#include

#include

#include

using

namespace

std;

const

int maxn=100005;

const

int maxm=200000;

struct edge

edges[maxm];

int head[maxn],tot;

void init()

void add_edge(int u,int v,int w)

int dist[maxn];

bool vis[maxn];

void dfs(int s)}}

}int main()

dfs(1);

int pos;

int dis=-1;

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

printf("%d\n",dis);

}return

0;}

二:牛客網小白月賽6:c——桃花

給定乙個樹,用魔法棒將一條鏈上的所有桃花摘下來,問最多能摘多少桃花

這就是求樹的最長鏈,其實樹也就是特殊的圖,用圖建邊,再呼叫之前的最長路思想就行,不過記住是雙向建邊而不是單向

#include 

#include

#include

#include

#include

#include

using

namespace

std;

const

int maxn=2000000;

struct edge

edges[maxn];

int head[maxn],tot;

bool vis[maxn];

int dist[maxn];

void init()

void add_edge(int u,int v)

int v0;

int dfs(int s)}}

return dist[v0];//返回最大的距離

}int main()

int dist0=dfs(1);

//printf("%d\n",dist0);

int dist1=dfs(v0);

printf("%d\n",dist1);

}return

0;}

求樹的直徑 樹中最長路

對於一顆有邊權的樹,它的直徑表示樹中最遠的兩個節點之間的距離,可以通過兩次深搜 廣搜 來求出直徑 從任意起點s開始,求出到s的最遠的節點node,然後再從node開始求出到node最遠的節點,搜尋的過程中更新節點的值和距離,貌似還可以用樹形dp來求,剛剛做的一道題,當時感覺是兩倍的權值和減去乙個最遠...

HDU4607 求樹中的最長鏈

題目 park visit 題意 給定一棵樹,從樹中的任意選乙個頂點出發,遍歷k個點的最短距離是多少?每條邊的長度為1 解析 就是求樹的最長鏈,假設求出的樹的最長鏈所包含的點數為m,那麼如果k m,那麼答案就是k 1,否則就是 k m 2 m 1 找樹中最長鏈方法是 可以通過經典的o n 的演算法求...

HDU4607 求樹中的最長鏈

題目 park visit 題意 給定一棵樹,從樹中的任意選乙個頂點出發,遍歷k個點的最短距離是多少?每條邊的長度為1 解析 就是求樹的最長鏈,假設求出的樹的最長鏈所包含的點數為m,那麼如果k m,那麼答案就是k 1,否則就是 k m 2 m 1 include include include us...