求最長路的思想還是套用大佬們的分析:
給定乙個無環圖,要求途中的最長路,思想就是任意找到乙個點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...