P1099 树网的核 NOIp2007

题目描述
设T=(V,E,W)T=(V,E,W)是一个无圈且连通的无向图(也称为无根树),每条边到有正整数的权,我们称TT为树网(treebetwork),其中VV,EE分别表示结点与边的集合,WW表示各边长度的集合,并设TT有nn个结点。

路径:树网中任何两结点aa,bb都存在唯一的一条简单路径,用d(a, b)d(a,b)表示以a, ba,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a, b)d(a,b)为a, ba,b两结点间的距离。

D(v, P)=\min{d(v, u)}D(v,P)=min{d(v,u)}, uu为路径PP上的结点。

树网的直径:树网中最长的路径成为树网的直径。对于给定的树网TT,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。

偏心距\mathrm{ECC}(F)ECC(F):树网T中距路径F最远的结点到路径FF的距离,即

\mathrm{ECC}(F)=\max{d(v, F),v \in V}ECC(F)=max{d(v,F),v∈V}
任务:对于给定的树网T=(V, E, W)T=(V,E,W)和非负整数ss,求一个路径FF,他是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过ss(可以等于s),使偏心距ECC(F)ECC(F)最小。我们称这个路径为树网T=(V, E, W)T=(V,E,W)的核(Core)。必要时,FF可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。

下面的图给出了树网的一个实例。图中,A-BA−B与A-CA−C是两条直径,长度均为2020。点WW是树网的中心,EFEF边的长度为55。如果指定s=11s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为88。如果指定s=0s=0(或s=1s=1、s=2s=2),则树网的核为结点FF,偏心距为1212。

输入输出格式
输入格式:
共nn行。

第11行,两个正整数nn和ss,中间用一个空格隔开。其中nn为树网结点的个数,ss为树网的核的长度的上界。设结点编号以此为1,2,…,n1,2,…,n。

从第22行到第nn行,每行给出33个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7247”表示连接结点22与44的边的长度为77。

输出格式:
一个非负整数,为指定意义下的最小偏心距。

输入输出样例
输入样例#1:
5 2
1 2 5
2 3 2
2 4 4
2 5 3

输出样例#1:
5
输入样例#2:
8 6
1 3 2
2 3 2
3 4 6
4 5 3
4 6 4
4 7 2
7 8 3
输出样例#2:
5
说明
40%40%的数据满足:5 \le n \le 155≤n≤15
70%70%的数据满足:5 \le n \le 805≤n≤80
100%100%的数据满足:5 \le n \le 300,0 \le s \le 10005≤n≤300,0≤s≤1000。边长度为不超过10001000的正整数

NOIP 2007 提高第四题

洛谷数据比较弱,bzoj 加强了

思路:
首先说一下朴素解法:一个很容易想到的是先两次 bfs 求出直径,然后在直径上枚举长度不超过s 的两点 p,q;p,q之间的即为 " Core " ,然后将核上的点标记为 已访问 ,然后dfs 求出核以外的点到核的距离,那么 max 即为偏心距,这些枚举的核的产生的偏心距的min 即为所求,此算法的 复杂度为 O( N³ ) ;
当然 N 比较小,可以暴力通过;

O( N ) 解法:用单调队列维护,即可 O( N ) 解决, 即为 max ( max { d[ uk ] },dis( u1,ui ) ,dis( uj,ut ) ) ,其中 1<=k<=t ;然后枚举每一个ui 即可;

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
typedef long long  ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const long long int mod = 1e9 + 7;
#define sq(x) (x)*(x)
#define eps 1e-6
const int N = 2500005;

inline int read()
{
	int x = 0, k = 1; char c = getchar();
	while (c < '0' || c > '9') { if (c == '-')k = -1; c = getchar(); }
	while (c >= '0' && c <= '9')x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
	return x * k;
}

ll gcd(ll a, ll b) {
	return b == 0 ? a : gcd(b, a%b);
}

int n, s;
int head[maxn], pre[maxn], vis[maxn];
int x, y, z;
int tot;
int dis[maxn];
int top, k;
int ans = inf;

struct node {
	int to, w, nxt;
}edge[maxn<<2];

void addedge(int x, int y, int z) {
	edge[++tot].to = y; edge[tot].w = z; edge[tot].nxt = head[x];
	//edge[++tot] = (node{ y,z,head[x] });
	head[x] = tot;
}

void dfs(int f, int x) {
	pre[x] = f;
	if (dis[x] > dis[k])k = x;
	for (int i = head[x]; i; i = edge[i].nxt) {
		int y = edge[i].to;
		if (vis[y] || y == f)continue;
		dis[y] = dis[x] + edge[i].w;
		dfs(x, y);
	}
}

int main()
{
	ios::sync_with_stdio(false);
	cin >> n >> s;
	for (int i = 1; i < n; i++) {
		cin >> x >> y >> z;
		addedge(x, y, z); addedge(y, x, z);
	}
	dis[1] = 0; dfs(0, 1);
	dis[k] = 0; dfs(0, k);
	top = k;

	for (int i = top, j = top; i; i = pre[i]) {
		while (dis[j] - dis[i] > s)j = pre[j];
		x = max(dis[top] - dis[j], dis[i]);
	//	cout << x << endl;
		ans = min(ans, x);
	}
	//cout << ans << endl;
	for (int i = top; i; i = pre[i])vis[i] = 1;

	for (int i = top; i; i = pre[i]) {
		k = i; dis[k] = 0;
		dfs(pre[i], i);
	}
	for (int i = 1; i <= n; i++) {
		ans = max(ans, dis[i]);
	//	cout << ans << endl;
	}
	cout << ans << endl;
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值