PAT-A 1021. Deepest Root(搜索)

    xiaoxiao2021-12-04  15

    题目链接:https://www.patest.cn/contests/pat-a-practise/1021

    题意:无环连通图也可以视为一棵树,选定图中任意一点作为根,如果这时候整个树的深度最大,该点称为 deepest root。 给定一个图,按升序输出所有 deepest root。如果给定的图有多个连通分量,则输出连通分量的数量。

    要想树的深度最大,那么树跟一定是一个度为1的点,所以我们只需要找到这些点,然后每个点搜一遍得到最大高度,然后按条件输出即可。当然开始得先判联通,我是用深搜判的。

    看网上其他人的做法,很多是先随便选一个点搜一遍,找出距离最大的点,以这个点再搜一遍,最后得到的距离最大的点加上这个点即是答案。这样做看似有道理,而且能过,但是有的情况是判断不了的,比如下面这组数据:

    in:

    5 1 2 1 3 2 4 2 5 out: 3 4 5

    因此这种算法虽然效率高但还需要改进。

    #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <queue> using namespace std; vector<int> m[10010]; //邻接表存图 int vis[10010]; int deg[10010]; //记录度数 int ans[10010]; int n; void dfs(int x) { //判联通 vis[x] = 1; for (int i = 0; i < m[x].size(); i++) { if (!vis[m[x][i]]) dfs(m[x][i]); } } struct node { int id, step; }; int bfs(int x) { //找最远距离 memset(vis, 0, sizeof(vis)); queue<node> q; node now, next; now.id = x, now.step = 0; q.push(now); vis[x] = 1; int maxl = 0; while(!q.empty()) { now = q.front(); if(now.step > maxl) maxl = now.step; q.pop(); for(int i = 0; i < m[now.id].size(); i++) { if(!vis[m[now.id][i]]) { vis[m[now.id][i]] = 1; next.id = m[now.id][i], next.step = now.step+1; q.push(next); } } } return maxl; } int main() { cin >> n; int x, y; for(int i = 0; i < n - 1; i++) { cin >> x >> y; deg[x]++; deg[y]++; m[x].push_back(y); m[y].push_back(x); } int cnt = 0; for (int i = 1; i <= n; i++) { if (!vis[i]) { cnt++; dfs(i); } } if(cnt == 1) { //联通分量个数为1 int maxn = 0; for(int i = 1; i <= n; i++) { if(deg[i] == 1) { ans[i] = bfs(i); if(ans[i] > maxn) maxn = ans[i]; } } for(int i = 1; i <= n; i++) { if(ans[i] == maxn) cout << i << endl; } } else cout << "Error: " << cnt << " components" << endl; return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-680349.html

    最新回复(0)