- 作者:老汪软件技巧
- 发表时间:2024-01-04 21:00
- 浏览量:
树的直径
树上最远两点(叶子结点)的距离。这里推荐dfs求树的直径。
性质 Cow
模板题,让你求距离最远的两个节点的距离,那么就是树的直径。树的直径怎么求,首先随便从一点u开始搜索找到离他最远的点t1,再从该点t1,搜索出离t1最远的点t2,t1跟t2就是树上最远两点。详细证明参考这篇博客传送门
下面展示一些 内联代码片。
#include
using namespace std;
const int N = 4e4 + 5;
struct E {
int to, nex, w;
}e[N << 1];
int cnt, head[N];
void Add(int u, int v, int w) {
e[++cnt].to = v;
e[cnt].w = w;
e[cnt].nex = head[u];
head[u] = cnt;
}
int mxd, mxu, t1, t2;
void dfs(int u, int fa, int d) {
if(d > mxd) {
mxd = d; //update deep
mxu = u; //update id
}
for(int i = head[u]; i; i = e[i].nex) {
int v = e[i].to, w = e[i].w;
if(v == fa) continue;
dfs(v, u, d + w);
}
}
void solve() {
int n, m, u, v, w;
char c;
cin >> n >> m;
for(int i = 1; i <= m; ++i) {
cin >> u >> v >> w >> c;
Add(u, v, w), Add(v, u, w);
}
dfs(1, -1, 0); //from node 1 find
mxd = 0;
t1 = mxu;
dfs(mxu, -1, 0);
t2 = mxu;
cout << mxd;
}
int main() {
solve();
}
求出所有节点离他最远的节点距离。
#include
#include
#define rep(i, a, b) for(int i = a; i <= b; ++i)
using namespace std;
const int N = 1e4 + 10;
int cnt, head[N];
struct E {
int to, nex, w;
}e[N << 1];
void Add(int u, int v, int w) {
e[++cnt].nex = head[u];
e[cnt].to = v;
e[cnt].w = w;
head[u] = cnt;
}
int n, mxd, mxu, t1, t2, dis[2][N];
void dfs1(int u, int fa, int d) {
if(d > mxd) {
mxd = d, mxu = u;
}
for(int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if(v == fa) continue;
dfs1(v, u, d + e[i].w);
}
}
void dfs2(int u, int fa, int d, int p) {
dis[p][u] = d;
for(int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if(v == fa) continue;
dfs2(v, u, d + e[i].w, p);
}
}
int main() {
while(cin >> n) {
cnt = 0;
rep(i, 0, n) head[i] = 0;
rep(i, 0, n) dis[0][i] = dis[1][i] = 0;
rep(i, 2, n) {
int u, w;
cin >> u >> w;
Add(u, i, w), Add(i, u, w);
}
mxd = mxu = 0;
dfs1(1, -1, 0);
t1 = mxu;
mxd = mxu = 0;
dfs1(t1, -1, 0);
t2 = mxu;
dfs2(t1, -1, 0, 0);
dfs2(t2, -1, 0, 1);
rep(i, 1, n) cout << max(dis[0][i], dis[1][i]) << "\n";
}
return 0;
}
F -
传送门
相距更远的两个点,fff值更大,求直径最远标记的两个点的中点距离就是答案。
#include
#define int long long
#define pii pair
#define debug(a) cout << #a << "=" << a <<"\n";
#define ios ios::sync_with_stdio(false), cin.tie(0);
#define rep(i, a, b) for(int i = a;i <= b; ++i)
#define multi int t;cin >> t;for(int i = 1;i <= t; ++i) solve()
using namespace std;
const int N = 2e5 + 10;
struct node {
int to, nex;
}e[N << 1];
int cnt, head[N];
void Add(int u, int v) {
e[++cnt].nex = head[u];
e[cnt].to = v;
head[u] = cnt;
}
int n, m, a[N], f[N];
map mp;
int mxd, mxu;
void dfs(int u, int fa, int d) {
if(d > mxd && mp[u]) {
mxu = u;
mxd = d;
}
for(int i = head[u]; i; i = e[i].nex) {
int v = e[i].to;
if(v == fa) continue;
dfs(v, u, d + 1);
}
}
void solve() {
cin >> n >> m;
int x, st, u, v;
mp.clear();
mxd = cnt = 0;
rep(i, 1, n) head[i] = 0;
rep(i, 1, m) {
cin >> x, mp[x]++;
st = x; //start point
}
rep(i, 2, n) {
cin >> u >> v;
Add(u, v), Add(v, u);
}
if(m == 1) {
cout << "0\n";
return;
}
dfs(st, -1, 0);
mxd = 0;
dfs(mxu, -1, 0);
cout << (mxd + 1) / 2 << '\n';
}
signed main() {
ios;
multi;
return 0;
}