标签:dfs 作用 alt 接下来 输入 == 表示 win 台电脑
给定一棵树,树中包含 n 个结点(编号1~n)和 n?1 条无向边,每条边都有一个权值。
请你在树中找到一个点,使得该点到树中其他结点的最远距离最近。
输入格式
第一行包含整数 n。
接下来 n?1 行,每行包含三个整数 ai,bi,ci,表示点 ai 和 bi 之间存在一条权值为 ci 的边。
输出格式
输出一个整数,表示所求点到树中其他结点的最远距离。
数据范围
1≤n≤10000,
1≤ai,bi≤n,
1≤ci≤105
输入样例:
5
2 1 1
3 2 1
4 3 1
5 1 1
输出样例:
2
第一次DFS求每个节点通过直接点的最远距离max1以及该儿子,并且还需要求一个次远距离max2。然后再求通过父节点可以到达的最远距离max3,可以是合并父节点的max1或max2或max3,但是当父节点的max1的儿子是该节点时,就不能合并,只能尝试合并max2,这就是记录次远距离的作用
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int head[N],cnt,ans;
struct eg{
int v,c,nex;
}edge[N*2];
int Max1[N],Max2[N],Max3[N];
int son1[N];
void addedge(int u,int v,int c){
edge[cnt]=(eg){v,c,head[u]};
head[u]=cnt++;
}
void dfs1(int u,int pre){
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v,c=edge[i].c;
if(pre==v) continue;
dfs1(v,u);
if(c+Max1[v]>=Max1[u]){
Max2[u]=Max1[u];
Max1[u]=c+Max1[v];
son1[u]=v;
}
else if(c+Max1[v]>Max2[u]){
Max2[u]=c+Max1[v];
}
}
//cout<<u<<" "<<Max1[u]<<" "<<son1[u]<<"--"<<Max2[u]<<" "<<son2[u]<<endl;
}
void dfs2(int u,int pre){
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v,c=edge[i].c;
if(pre==v) continue;
if(son1[u]!=v){
Max3[v]=Max1[u]+c;
}
else {
Max3[v]=Max2[u]+c;
}
Max3[v]=max(Max3[u]+c,Max3[v]);
dfs2(v,u);
}
}
int main(){
int n;
cin>>n;
memset(head,-1,sizeof head);
for(int i=1,u,v,c;i<n;++i){
cin>>u>>v>>c;
addedge(u,v,c);
addedge(v,u,c);
}
dfs1(1,0);
dfs2(1,0);
int ans=1000000000;
for(int i=1;i<=n;++i)
ans=min(ans,max(Max1[i],max(Max2[i],Max3[i])));
cout<<ans<<endl;
return 0;
}
一所学校前一段时间买了第一台计算机(所以这台计算机的ID是1)。
近年来,学校又购买了N-1台新计算机。
每台新计算机都与之前买进的计算机中的一台建立连接。
现在请你求出第i台计算机到距离其最远的计算机的电缆长度。
例如,上图中距离计算机1最远的是计算机4,因此 S1=3;距离计算机2最远的是计算机4和5,因此 S2=2;距离计算机3最远的是计算机5,所以 S3=3;同理,我们也得到 S4=4,S5=4。
输入格式
输入包含多测试数据。
每组测试数据第一行包含整数N。
接下来N-1行,每行包含两个整数,第 i 行的第一个整数表示第 i 台电脑买入时连接的电脑编号,第二个整数表示这次连接花费的电缆长度。
输出格式
每组测试数据输出N行。
第i行输出第i台电脑的Si。
数据范围
1≤N≤10000,
电缆总长度不超过109
输入样例:
5
1 1
2 1
3 1
1 1
输出样例:
3
2
3
4
4
带上边权
#include<bits/stdc++.h>
using namespace std;
const int N=10010;
int head[N],cnt,ans;
struct eg{
int v,c,nex;
}edge[N*2];
int Max1[N],Max2[N],Max3[N];
int son1[N],son2[N];
void addedge(int u,int v,int c){
edge[cnt]=(eg){v,c,head[u]};
head[u]=cnt++;
}
void dfs1(int u,int pre){
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v,c=edge[i].c;
if(pre==v) continue;
dfs1(v,u);
if(c+Max1[v]>=Max1[u]){
Max2[u]=Max1[u];
son2[u]=son1[u];
Max1[u]=c+Max1[v];
son1[u]=v;
}
else if(c+Max1[v]>Max2[u]){
Max2[u]=c+Max1[v];
son2[u]=v;
}
}
//cout<<u<<" "<<Max1[u]<<" "<<son1[u]<<"--"<<Max2[u]<<" "<<son2[u]<<endl;
}
void dfs2(int u,int pre){
for(int i=head[u];~i;i=edge[i].nex){
int v=edge[i].v,c=edge[i].c;
if(pre==v) continue;
if(son1[u]!=v){
Max3[v]=Max1[u]+c;
}
else {
Max3[v]=Max2[u]+c;
}
Max3[v]=max(Max3[u]+c,Max3[v]);
dfs2(v,u);
}
}
int main(){
int n;
cin>>n;
memset(head,-1,sizeof head);
for(int i=2,u,v,c;i<n;++i){
cin>>u>>v>>c;
addedge(u,v,c);
addedge(v,u,c);
}
dfs1(1,0);
dfs2(1,0);
int ans=1000000000;
for(int i=1;i<=n;++i)
ans=min(ans,max(Max1[i],max(Max2[i],Max3[i])));
cout<<ans<<endl;
return 0;
}
标签:dfs 作用 alt 接下来 输入 == 表示 win 台电脑
原文地址:https://www.cnblogs.com/jjl0229/p/12652455.html