算法概论习题1001Forest
题目意思,一个有向图,若有环(不仅仅是自环)或某个点入度大于等于2则不合法,否则合法,输出深度和所有连通分量在同一层的最大节点数。
判断一个没有入度>=2有向图是否有环:
只需一个判断条件:对所有入度为0的点进行DFS,若所有的点都访问到了,则无环,否则有环
也就是说,只要保证每个点入度≥2,则该图的连通分量只能有几种情况:孤立点,非环,全部点收尾相接形成的环(不存在入度为0的点)
所以对入度为0的点进行DFS前两种情况必定能访问到该连通分量内所有的点。
http://soj.me/show_problem.php?pid=1001&cid=970
#include <iostream> #include <vector> #include <cstring> #include <algorithm> using namespace std; #define Max 10000 int n, m, vis[Max], layer[Max], in[Max]; vector<int> v[Max]; bool valid; void dfs(int x, int l) { vis[x] = 1; layer[l]++; for (int i = 0; i < v[x].size(); ++i) dfs(v[x][i], l+1); } int main() { while (cin >> n >> m, n) { valid = 1; memset(vis, 0, sizeof(vis)); memset(in, 0, sizeof(in)); memset(layer, 0, sizeof(layer)); memset(v, 0, sizeof(v)); int a, b; for (int i = 0; i < m; ++i) { cin >> a >> b; v[a].push_back(b); in[b]++; if (in[b] >= 2) { valid = 0; } } //入度≥2的点的INVALID if (!valid) { cout << "INVALID" << endl; continue; } //对所有入度为0的点进行深搜 for (int i = 1; i <= n; ++i) if (in[i] == 0) dfs(i, 0); //若没有遍历所有的点则有环 for (int i = 1; i <= n; ++i) { if (!vis[i]) { valid = 0; break; } } //DFS没有遍历所有的点的INVALID if (!valid) { cout << "INVALID" << endl; continue; } //depth的值就是layer[i]不为0的i值中最大的那个 int depth = -1; for (int i = 0; i < n; ++i) { if (layer[i]) depth++; } cout << depth << ' ' << *max_element(layer,layer+n) << endl; } }
转载请注明出处http://www.cnblogs.com/chenyg32/