【原题】【noip2007 T4】树网的核(图论,最短路)
2010-11-11 18:10
405 查看
问题
描述 Description
【问题描述】
设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V, E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。
路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a,b)为a,b两结点间的距离。
一点v到一条路径P的距离为该点与P上的最近的结点的距离:
d(v,P)=min{d(v,u),u为路径P上的结点}。
树网的直径:树网中最长的路径称为树网的直径。对于给定的树网T,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。
偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离, 即
ECC(F)=max{d(v,F),v∈V}.
任务:对于给定的树网T=(V, E,W)和非负整数s,求一个路径F,它是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过s(可以等于s),使偏心距ECC(F)最小。我们称这个路径为树网T=(V,E,W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。
下面的图给出了树网的一个实例。图中,A-B与A-C是两条直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8。如果指定s=0(或s=1、s=2),则树网的核为结点F,偏心距为12。
输入格式 Input Format
输入文件包含n行:
第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号依次为1, 2, ..., n。
从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。
所给的数据都是正确的,不必检验。
5 2
1 2 5
2 3 2
2 4 4
2 5 3
5
分析
最简单的方法——枚举。枚举每条直径,枚举直径上的每个路径,计算偏心率。
对于路径的长度,我们可以用spfa进行预处理,时间复杂度接近n2
对于偏心距我们可以得到如下的计算方法
ecc:=max{min{dist[st,i],dist[st,j]},min{dist[ed,i],dist[ed,j]}};
st是直径的起点,ed为直径终点,i为枚举的路径的一端,j为另一端.
为什么捏,我们假设存在非直径端点的一点k,如果dis[k,i]<dis[i,st]那么st为最远距离,如果dis[k,i]>dis[i,st]那么当前的直径就不是最长的路径,就和它是直径相矛盾,所以我们对于一条直径上的路径可以得到如上计算偏心距的方法
插一副图帮助理解
反思
noip考察图论不会离开最短路,都是经典算法,比如最优贸易,关键是如何根据题意改造经典算法。贪心是不错的选择,经典算法可以做预处理,可以多次使用。在考虑时一定要尽量发挥经典算法的作用
code
描述 Description
【问题描述】
设T=(V, E, W) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称T为树网(treenetwork),其中V, E分别表示结点与边的集合,W表示各边长度的集合,并设T有n个结点。
路径:树网中任何两结点a,b都存在唯一的一条简单路径,用d(a,b)表示以a,b为端点的路径的长度,它是该路径上各边长度之和。我们称d(a,b)为a,b两结点间的距离。
一点v到一条路径P的距离为该点与P上的最近的结点的距离:
d(v,P)=min{d(v,u),u为路径P上的结点}。
树网的直径:树网中最长的路径称为树网的直径。对于给定的树网T,直径不一定是唯一的,但可以证明:各直径的中点(不一定恰好是某个结点,可能在某条边的内部)是唯一的,我们称该点为树网的中心。
偏心距ECC(F):树网T中距路径F最远的结点到路径F的距离, 即
ECC(F)=max{d(v,F),v∈V}.
任务:对于给定的树网T=(V, E,W)和非负整数s,求一个路径F,它是某直径上的一段路径(该路径两端均为树网中的结点),其长度不超过s(可以等于s),使偏心距ECC(F)最小。我们称这个路径为树网T=(V,E,W)的核(Core)。必要时,F可以退化为某个结点。一般来说,在上述定义下,核不一定只有一个,但最小偏心距是唯一的。
下面的图给出了树网的一个实例。图中,A-B与A-C是两条直径,长度均为20。点W是树网的中心,EF边的长度为5。如果指定s=11,则树网的核为路径DEFG(也可以取为路径DEF),偏心距为8。如果指定s=0(或s=1、s=2),则树网的核为结点F,偏心距为12。
输入格式 Input Format
输入文件包含n行:
第1行,两个正整数n和s,中间用一个空格隔开。其中n为树网结点的个数,s为树网的核的长度的上界。设结点编号依次为1, 2, ..., n。
从第2行到第n行,每行给出3个用空格隔开的正整数,依次表示每一条边的两个端点编号和长度。例如,“2 4 7”表示连接结点2与4的边的长度为7。
所给的数据都是正确的,不必检验。
5 2
1 2 5
2 3 2
2 4 4
2 5 3
5
分析
最简单的方法——枚举。枚举每条直径,枚举直径上的每个路径,计算偏心率。
对于路径的长度,我们可以用spfa进行预处理,时间复杂度接近n2
对于偏心距我们可以得到如下的计算方法
ecc:=max{min{dist[st,i],dist[st,j]},min{dist[ed,i],dist[ed,j]}};
st是直径的起点,ed为直径终点,i为枚举的路径的一端,j为另一端.
为什么捏,我们假设存在非直径端点的一点k,如果dis[k,i]<dis[i,st]那么st为最远距离,如果dis[k,i]>dis[i,st]那么当前的直径就不是最长的路径,就和它是直径相矛盾,所以我们对于一条直径上的路径可以得到如上计算偏心距的方法
插一副图帮助理解
反思
noip考察图论不会离开最短路,都是经典算法,比如最优贸易,关键是如何根据题意改造经典算法。贪心是不错的选择,经典算法可以做预处理,可以多次使用。在考虑时一定要尽量发挥经典算法的作用
code
program liukee; var dis,map:array[0..300,0..300] of longint; a:array[0..300,0..300] of longint; v:array[0..300] of boolean; q:array[0..1000000] of longint; n,s,i,j,ed,st,ans,len,ecc:longint; function max(a,b:longint):longint; begin if a>b then exit(a); exit(b); end; function min(a,b:longint):longint; begin if a<b then exit(a); exit(b); end; procedure init; var i,x,y,z:longint; begin readln(n,s); for i:=1 to n-1 do begin read(x,y,z); map[x,y]:=z; map[y,x]:=z; inc(a[x,0]); a[x,a[x,0]]:=y; inc(a[y,0]); a[y,a[y,0]]:=x; end; end; procedure spfa(s:longint);//求最短路 var i,l,r,now:longint; begin for i:=1 to n do dis[s,i]:=maxlongint>>1; fillchar(v,sizeof(v),0); fillchar(q,sizeof(q),0); dis[s,s]:=0; v[s]:=true; q[1]:=s; l:=0;r:=1; while l<=r do begin inc(l); now:=q[l]; for i:=1 to a[now,0] do if dis[s,a[now,i]]>dis[s,now]+map[now,a[now,i]] then begin dis[s,a[now,i]]:=dis[s,now]+map[now,a[now,i]]; if not v[a[now,i]] then begin inc(r); q[r]:=a[now,i]; v[a[now,i]]:=true; end; end; v[now]:=false; end; end; begin init; for i:=1 to n do spfa(i); len:=-maxlongint;//寻找直径长度 for i:=1 to n do for j:=1 to n do if dis[i,j]>len then len:=dis[i,j]; ans:=maxlongint; for st:=1 to n-1 do//枚举起点 for ed:=st+1 to n do//枚举直径终点 if dis[st,ed]=len then//找到的是直径 for i:=1 to n do//枚举路径 if dis[st,i]+dis[i,ed]=len then for j:=1 to n do if(dis[st,j]+dis[j,ed]=len)and(dis[i,j]<=s) then begin ecc:=max(min(dis[i,st],dis[j,st]),min(dis[i,ed],dis[j,ed]));//计算ecc if ecc<ans then ans:=ecc; end; writeln(ans); end.
相关文章推荐
- 【NOIP2007提高组T4】树网的核-Floyd最短路+枚举
- [NOIP2007]树网的核【搜索,最短路…
- [树的直径] BZOJ 1999 [Noip2007]Core树网的核
- BZOJ1999 && noip2007树网的核
- BZOJ1999: [Noip2007]Core树网的核(洛谷P1099)
- noip2007树网的核
- 1999: [Noip2007]Core树网的核
- BZOJ 1999: [Noip2007]Core树网的核【最长链】
- BZOJ 1999: [Noip2007]Core树网的核[dfs]
- 1999: [Noip2007]Core树网的核 树形dp 单调队列
- 【BZOJ】1999 [Noip2007]Core树网的核 树的直径+DFS
- 【DFS好题】BZOJ1999- [Noip2007]Core树网的核(数据加强版)
- [noip2007]树网的核(链上乱搞)
- noip2007普及组T1--T4题解
- 【图论经典题】NOIP2013 普及组 T4 车站分级(两种方法)
- bzoj 1999: [Noip2007]Core树网的核【树的直径+单调队列】
- BZOJ 1999 [Noip2007]树网的核(2282 [Sdoi2011]消防) - 树的直径+单调队列
- 1999: [Noip2007]Core树网的核
- BZOJ_1999_[Noip2007]Core树网的核_单调队列+树形DP
- NOIP 2007树网的核