用兩邊dfs求出直徑,用f記錄fa,這樣就記錄下了直徑的路徑,將直徑上的點vis標記為1。然後列舉左右端點(或者尺取法,但不會)。
貪心考慮對答案的貢獻:
假設直徑的兩個端點為a和b,當前左右端點為i,j,
對答案的貢獻只有a,i之間的距離、b,j之間的距離、i,j中每個節點的子樹的最遠距離。
那麼可以對於直徑上的每乙個節點做一次關於它的子樹(除直徑)的dfs,找出子樹最遠距離,存在dt中。注意不要每更換一次左右端點就重新求一遍,因為vis
會影響(坑)。
ac**:
1 #include2 #include3 #include4 #include5ac**using
namespace
std;
6int
n,s;
7const
int n=400;8
int tot,ans=0x7f7f7f7f
,anss,ansss;
9int
head[n];
10int
f[n],maxd,dis[n],diss[n],dt[n];
11int
p,vis[n];
12struct
nodeedge[n<<1
];15
void add(int u,int v,int
w)21
void dfs(int u,int
fa)27
for(int i=head[u];i!=-1;i=edge[i].next)34}
35void dfsd(int
u)44}45
intmain()
54 dfs(1,-1
);55 memset(dis,0,sizeof
(dis));
56 memset(f,-1,sizeof
(f));
57 memset(vis,0,sizeof
(vis));
58int a=p;
59 maxd=0
;60 dfs(p,-1
);61
int b=p;
62 memset(vis,0,sizeof
(vis));
63for(int i=b;i!=-1;i=f[i]) vis[i]=1;64
for(int i=b;i!=-1;i=f[i])
71 anss=max(anss,maxd);72}
73 ans=min(ans,anss);74}
75}76 printf("%d"
,ans);
77return0;
78 }
洛谷P1099 樹網的核
題目 對於這種題目描述比較長的題,可以考慮簡化題意。簡化後的題意 給定一棵帶邊權無根樹 在其直徑上求出一段長度不超過s的路徑f,使得離路徑距離最遠的點到路徑的距離最短。求最短距離。根據題目範圍,直接暴力floyd求多源最短路徑。然後 n 2 求出直徑和直徑端點。搜尋求出直徑上的點。然後再暴力找出所有...
洛谷 P1099 樹網的核
設t v,e,w t v,e,w 是乙個無圈且連通的無向圖 也稱為無根樹 每條邊到有正整數的權,我們稱tt為樹網 treebetwork 其中vv,ee分別表示結點與邊的集合,ww表示各邊長度的集合,並設tt有nn個結點。路徑 樹網中任何兩結點aa,bb都存在唯一的一條簡單路徑,用d a,b d a...
洛谷 P1099 樹網的核 題解
樓上的大佬似乎都用的dfs,像我這種蒟蒻只會用暴力的floyd演算法。不過,看到這道題規模只有300,floyd演算法不會有問題。首先用floyd演算法預處理點對之間的距離,接下來窮舉每一對點構成的路徑 假裝每一條路徑就是樹網的核 如果路徑長 s,則計算其它點到該路徑的最大距離,取窮舉到的所有路徑中...