浙大 PAT Advanced level 1021. Deepest Root (25)
2016-05-13 18:08
417 查看
A graph which is connected and acyclic can be considered a tree. The height of the tree depends on the selected root. Now you are supposed to find the root that results in a highest tree. Such a root is called the deepest root.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent
nodes' numbers.
Output Specification:
For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components
in the graph.
Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:
Error: 2 components
将不含环的图作为一颗树,求让树高度最大的所有根节点。求树的高度很明显可以用bfs。
可以遍历图的每一个节点求高度,然后输出所有高度最大的节点。但需要注意case中有许多稀疏图,只有用邻接表的方式才可以通过所有case,用二维数组表示树在遍历过程中会超时。
实际上更简单的想法是,首先选取任一一个节点做bfs,并记录下使得树高度最高的所有顶点的集合set1,然后从set1中任选一点做bfs,记录下所有使得树高度最高的顶点结合set2,set1和set2的并集即为最终的结果。
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<=10000) which is the number of nodes, and hence the nodes are numbered from 1 to N. Then N-1 lines follow, each describes an edge by given the two adjacent
nodes' numbers.
Output Specification:
For each test case, print each of the deepest roots in a line. If such a root is not unique, print them in increasing order of their numbers. In case that the given graph is not a tree, print "Error: K components" where K is the number of connected components
in the graph.
Sample Input 1:
5
1 2
1 3
1 4
2 5
Sample Output 1:
3
4
5
Sample Input 2:
5
1 3
1 4
2 5
3 4
Sample Output 2:
Error: 2 components
将不含环的图作为一颗树,求让树高度最大的所有根节点。求树的高度很明显可以用bfs。
可以遍历图的每一个节点求高度,然后输出所有高度最大的节点。但需要注意case中有许多稀疏图,只有用邻接表的方式才可以通过所有case,用二维数组表示树在遍历过程中会超时。
实际上更简单的想法是,首先选取任一一个节点做bfs,并记录下使得树高度最高的所有顶点的集合set1,然后从set1中任选一点做bfs,记录下所有使得树高度最高的顶点结合set2,set1和set2的并集即为最终的结果。
/* 可以AC,效率很高 0 答案正确 1 256 13/13 1 答案正确 1 296 2/2 2 答案正确 2 304 5/5 3 答案正确 23 1536 2/2 4 答案正确 1 256 2/2 5 答案正确 1 256 1/1 */ #include <iostream> #include <vector> #include <queue> #include <set> using namespace std; const int white = 0; const int gray = 1; const int black = 2; typedef struct node { int color; int height; vector<int> adj; }node; int N; vector<node> graph; void dfs(int index) { int k; graph[index].color = gray; for (unsigned int i = 0; i < graph[index].adj.size(); ++i) { k = graph[index].adj[i]; if (white == graph[k].color) { dfs(k); } } graph[index].color = black; } void bfs(int root, vector<int> &res) { int max_height = 0; int index; int k; queue<int> nq; for (int i = 0; i != N; ++i) { graph[i].color = white; graph[i].height = 0; } nq.push(root); graph[root].color = gray; while (!nq.empty()) { index = nq.front(); nq.pop(); graph[index].color = black; for (unsigned int i = 0; i != graph[index].adj.size(); ++i) { k = graph[index].adj[i]; if (white == graph[k].color) { graph[k].height = graph[index].height + 1; graph[k].color = gray; nq.push(k); if (graph[k].height > max_height) { max_height = graph[k].height; } } } } for (int i = 0; i != N; ++i) { if (graph[i].height == max_height) { res.push_back(i); } } return ; } int main() { int ni, nj; vector<int> res1, res2; set<int> res_all; int parts = 0; bool flag = false; cin >> N; graph.resize(N); for (int i = 0; i != N; ++i) { graph[i].color = white; graph[i].height = 0; } for (int i = 0; i != N-1; ++i) { cin >> ni >> nj; --ni; --nj; graph[ni].adj.push_back(nj); graph[nj].adj.push_back(ni); } for (int i = 0; i != N; ++i) { if (white == graph[i].color) { dfs(i); ++parts; } } if (1 != parts) { cout << "Error: " << parts << " components" << endl; return 0; } bfs(0, res1); bfs(res1.at(0), res2); ni = nj = 0; for (unsigned int i = 0; i != res1.size(); ++i) { res_all.insert(res1[i]); } for (unsigned int i = 0; i != res2.size(); ++i) { res_all.insert(res2[i]); } for (set<int>::const_iterator iter = res_all.begin(); iter != res_all.end(); ++iter) { cout << (*iter)+1 << endl; } return 0; } /* 可以ac 0 答案正确 1 256 13/13 1 答案正确 1 256 2/2 2 答案正确 1 300 5/5 3 答案正确 984 1212 2/2 4 答案正确 1 256 2/2 5 答案正确 1 316 1/1 */ /* 稀疏图用邻接表效率更高*/ #if 0 #include <iostream> #include <vector> #include <queue> using namespace std; const int white = 0; const int gray = 1; const int black = 2; typedef struct node { int color; int start; int finish; int height; vector<int> adj; }node; int N; vector<node> graph; int ntime = 0; int parts = 0; void dfs(int index) { int k; graph[index].color = gray; graph[index].start = ntime++; for (unsigned int i = 0; i < graph[index].adj.size(); ++i) { k = graph[index].adj[i]; if (white == graph[k].color) { dfs(k); } } graph[index].color = black; graph[index].finish = ntime++; } int bfs(int root) { int ret = 0; int index; int k; queue<int> nq; for (int i = 0; i != N; ++i) { graph[i].color = white; graph[i].height = 0; } nq.push(root); graph[root].color = gray; while (!nq.empty()) { index = nq.front(); nq.pop(); graph[index].color = black; for (unsigned int i = 0; i != graph[index].adj.size(); ++i) { k = graph[index].adj[i]; if (white == graph[k].color) { graph[k].height = graph[index].height + 1; graph[k].color = gray; nq.push(k); if (graph[k].height > ret) { ret = graph[k].height; } } } } return ret; } int main() { int ni, nj, nh; int max_height = 0; vector<int> results; cin >> N; graph.resize(N); for (int i = 0; i != N; ++i) { graph[i].color = white; graph[i].height = 0; } for (int i = 0; i != N-1; ++i) { cin >> ni >> nj; --ni; --nj; graph[ni].adj.push_back(nj); graph[nj].adj.push_back(ni); } for (int i = 0; i != N; ++i) { if (white == graph[i].color) { dfs(i); ++parts; } } if (1 != parts) { cout << "Error: " << parts << " components" << endl; } else { for (int i = 0; i != N; ++i) { /************************************************************************/ /* 注释掉下面的if 语句可以ac */ /* 考虑输入:2 1 2 */ /************************************************************************/ /* if (graph[i].start + 1 == graph[i].finish) */ { nh = bfs(i); if (nh > max_height) { max_height = nh; results.clear(); results.push_back(i); } else { if (nh == max_height) { results.push_back(i); } } } } for (unsigned int i = 0; i != results.size(); ++i) { cout << results[i]+1 << endl; } } return 0; } #endif #if 0 // 超时 #include <iostream> #include <queue> using namespace std; int graph[10002][10002]; /* 1表示存在路径*/ int visited[10002]; /* 1为已经访问*/ int result[10002]; void DFS(int root, int num) { visited[root] = true; for (int i = 1; i <= num; ++i) { if (1 == graph[root][i] && 0 == visited[i]) { DFS(i, num); } } } // 返回正值表示以root为根的树的最大深度 // 返回负值表示图有多少个不连通的部分 int levelCount(int root, int num) { int level; // 记录以root为根的树的最大深度 int part; // 记录图有多少个相互不连通的区域(针对"Error: K components") bool flag = true; // 如果是连通图, 则为true; 反之为false int count, temp; queue<int> Q; for (int i = 1; i <= num; ++i) { visited[i] = 0; } Q.push(root); count = 1; level = 0; visited[root] = 1; part = 1; while(!Q.empty()) { while(count--) { temp = Q.front(); Q.pop(); for (int i = 1; i <= num; ++i) { if (1 == graph[temp][i] && 0 == visited[i]) { visited[i] = 1; Q.push(i); } } } count = Q.size(); ++level; } for (int i = 1; i <= num; ++i) { // 存在未被访问的点 if (0 == visited[i]) { flag = false; DFS(i, num); ++part; } } if (flag) { return level; } else { return -part; } } int main() { int num; int row, col; int maxlevel = 0; cin >> num; for (int i = 1; i != num; ++i) { cin >> row >> col; graph[row][col] = graph[col][row] = 1; } for (int i = 1; i <= num; ++i) { result[i] = levelCount(i, num); if (result[i] < 0) { cout << "Error: " << -result[i] << " components" << endl; system("pause"); return 0; } if (result[i] > maxlevel) { maxlevel = result[i]; } } for (int i = 1; i <= num; ++i) { if (result[i] == maxlevel) { cout << i << endl; } } system("pause"); return 0; } #endif
相关文章推荐
- 常见HTTP状态(304,200等)
- redis test
- 大数据Java基础第八天作业
- android WebView拦截js弹窗界面无响应问题
- 用fiddler模拟网络请求超时
- Android-Activity生命周期的理解
- Android Matrix手势缩放自定义view 不止于Imageview
- 110.[Leetcode]Balanced Binary Tree
- GBDT(MART) 迭代决策树入门教程 | 简介
- 描绘用户场景
- Linux 目录结构
- Centos下使用yum安装MariaDB
- 动态规划 中级题解 路径记录
- python中操作数据库中游标的使用方法
- mysql unique option prefix myisam_recover instead of myisam-recover-options的解决方法
- 【BZOJ2875】[Noi2012]随机数生成器【矩阵快速幂】
- UITextField限制输入字数高亮状态下输入框内真实类容与textFiled(解决中文输入问题)
- 列出一些你常见的运行时异常(非检查异常)?
- Redis Cluster 实现细节
- 浙大 PAT Advanced level 1020. Tree Traversals (25)