萌新,刚学树形DP,求调代码
查看原帖
萌新,刚学树形DP,求调代码
188970
Twiter_ln楼主2024/7/24 13:05

Rt,按照题解第一篇的思路做的。 Rt,按照题解第一篇的思路 做的。


#include<bits/stdc++.h>

using namespace std;
const int N = 2e5 + 37;
typedef long long lli;

int n, x, y, z;
int ls, rs;
lli ld[N], rd[N];
vector <int> c;

struct pot {
	int v, val;
	int nxt;
}E[N<<2];
int head[N], tot = 1;
inline void Add_edge(int u, int v, int val) {
	E[++tot].v = v;
	E[tot].val = val;
	E[tot].nxt = head[u];
	head[u] = tot;
}

bool vis[N];
lli dep[N];
int gen;
lli maxx;
void dfs(int u) { // Ê÷µÄÖ±¾¶ 
	int v, val;
	for(int i = head[u]; i; i = E[i].nxt) {
		v = E[i].v;
		val = E[i].val;
		if(vis[v]) continue;
		vis[v] = 1;
		dep[v] = dep[u] + val;
		dfs(v);
		if(dep[v] > maxx) {
			gen = v;
			maxx = dep[v];
		}
	}
}
bool pp = false;
void dfs1(int u) {
	if(dep[u] == maxx) {
		pp = 1;
		c.push_back(u);
		return;
	}
	int v;
	for(int i = head[u]; i; i = E[i].nxt) {
		v = E[i].v;
		if(vis[v]) continue;
		vis[v] = 1;
		dfs1(v);
		if(pp) {
			c.push_back(u);
			return ;
		}
	}
}
void dfs2(int u) {
	int v, val;
	for(int i = head[u]; i; i = E[i].nxt) {
		v = E[i].v;
		val = E[i].val;
		if(vis[v]) continue;
		vis[v] = 1;
		dfs(v);
		dep[u] = max(dep[u], dep[v] + val);
	}
}

int main() {
	
	scanf("%d", &n);
	for(int i = 1; i <= n-1; ++ i) {
		scanf("%d%d%d", &x, &y, &z );
		Add_edge(x, y, z);
		Add_edge(y, x, z);
	}
	
	vis[1] = 1;
	dfs(1);
	ls = gen;
	memset(vis, 0, sizeof(vis));
	maxx=0; 
	vis[ls] = 1;
	dep[ls] = 0;
	dfs(ls);
	rs = gen;
	for(int i = 1; i <= n; ++ i) ld[i] = dep[i];
//	cout<<"LS: RS: "<<ls<<" "<<rs<<endl;
	printf("%lld\n", maxx);
	
	memset(vis, 0, sizeof(vis));
	vis[rs] = 1;
	dep[rs] = 0;
	dfs(rs);
	for(int i = 1; i <= n; ++ i) rd[i] = dep[i];
	// 直径上的点 到左右端点的距离
	
	memset(vis, 0, sizeof(vis));
	dfs1(rs); // ls-->rs
//	for(int i = 0; i < c.size(); ++ i) cout<<c[i]<<" ";
//	putchar('\n');
//	cout<<c.size()<<"\n";
	memset(vis, 0, sizeof(vis));
	for(int i = 0; i < c.size(); ++ i) vis[c[i]] = 1;
	
	memset(dep, 0, sizeof(dep));
	for(int i = 0; i < c.size(); ++ i) {
		dfs2(c[i]);
	} // 在不经过直径上的点下,每个直径上的点的maxdis 
	
//	for(int i = 1; i <=n ;++ i) {
////		cout<<ld[i]<<" "<<rd[i]<<" "<<dep[i]<<"\n";
//	}
	
	int p1 = 0, p2 = c.size() - 1;
	for(int i = 0; i < c.size(); ++ i) {
		if(dep[c[i]] == rd[c[i]]) {
			p2 = i;
			break;
		} else if(dep[c[i]] == ld[c[i]]) p1 = i;
	}
//	cout<<p1<<" "<<p2<<"\n";
	printf("%d\n", p2 - p1);
	
	return 0;
}
/*

6
3 1 1000
1 4 10
4 2 100
4 5 50
4 6 100
:
1110
2

7
1 2 1
2 3 1
2 4 1
2 5 1
5 6 1
5 7 1
:
3
1

*/
2024/7/24 13:05
加载中...