https://pintia.cn/problem-sets/994805342720868352/problems/994805482919673856
方法一:
- 數組模擬鄰接表
- 第一步: 爆搜dfs求連通塊
- 第二步: 暴力枚舉每一個點求其最遠的距離
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
int h
[N
],e
[N
],ne
[N
],idx
,n
;
int st
[N
],cnt
;
void add(int a
,int b
)
{e
[idx
]=b
,ne
[idx
]=h
[a
],h
[a
]=idx
++;
}
void dfs(int u
)
{st
[u
]=1;for(int i
=h
[u
];i
!=-1;i
=ne
[i
]){int j
=e
[i
]; if(!st
[j
]) dfs(j
);}
}
int dfs1(int u
,int father
)
{int depth
=0;for(int i
=h
[u
];i
!=-1;i
=ne
[i
]){int j
=e
[i
];if(j
==father
) continue;depth
=max(depth
,dfs1(j
,u
)+1); }return depth
;
}
int main(void)
{cin
>>n
;memset(h
,-1,sizeof h
);for(int i
=0;i
<n
-1;i
++){int a
,b
; cin
>>a
>>b
;add(a
,b
),add(b
,a
);}for(int i
=1;i
<=n
;i
++) if(!st
[i
]) dfs(i
),cnt
++;if(cnt
==1){vector
<int>ve
;int max_len
=0;for(int i
=1;i
<=n
;i
++){int len
=dfs1(i
,-1);if(len
>max_len
){max_len
=len
;ve
.clear();ve
.push_back(i
);}else if(len
==max_len
) ve
.push_back(i
);}for(int i
=0;i
<ve
.size();i
++) cout
<<ve
[i
]<<endl
;}else printf("Error: %d components",cnt
);return 0;
}
方法二:
- vector存鄰接表
- 第一步: 并查集求連通塊
- 第二步: 暴力枚舉每一個點求其最遠的距離
#include<bits/stdc++.h>
using namespace std
;
const int N
=1e5+10;
vector
<int>ve
[N
];
int p
[N
],n
;
int find(int x
)
{if(x
!=p
[x
]) p
[x
]=find(p
[x
]);return p
[x
];
}
int dfs(int u
,int father
)
{int depth
=0;for(int i
=0;i
<ve
[u
].size();i
++){if(ve
[u
][i
]==father
) continue;depth
=max(depth
,dfs(ve
[u
][i
],u
)+1);}return depth
;
}
int main(void)
{cin
>>n
; int cnt
=n
;for(int i
=1;i
<=n
;i
++) p
[i
]=i
;for(int i
=0;i
<n
-1;i
++){int a
,b
; scanf("%d%d",&a
,&b
);ve
[a
].push_back(b
);ve
[b
].push_back(a
);if(find(a
)!=find(b
)){p
[find(a
)]=find(b
);cnt
--;}}if(cnt
>1) printf("Error: %d components",cnt
);else {vector
<int>ans
;int max_len
=0;for(int i
=1;i
<=n
;i
++){int len
=dfs(i
,-1);if(len
>max_len
){max_len
=len
;ans
.clear();ans
.push_back(i
);}else if(len
==max_len
) ans
.push_back(i
);}for(int i
=0;i
<ans
.size();i
++) printf("%d\n",ans
[i
]);}return 0;
}
時間上的比較: 第一種比第二種快了[100,300]ms 如果第一種也用并查集時間會更快。第二種的vector的時間花費有點大
總結
以上是生活随笔為你收集整理的1021 Deepest Root (25 分) 【难度: 中 / 知识点: 树的直径 连通块】的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。