Sicily---1034. Forest
来源:互联网 发布:网络监控调试方案 编辑:程序博客网 时间:2024/05/29 13:15
并查集在有向图中的应用
题目:
Description
In the field of computer science, forest is important and deeply researched , it is a model for many data structures . Now it’s your job here to calculate the depth and width of given forests.
Precisely, a forest here is a directed graph with neither loop nor two edges pointing to the same node. Nodes with no edge pointing to are roots, we define that roots are at level 0 . If there’s an edge points from node A to node B , then node B is called a child of node A , and we define that B is at level (k+1) if and only if A is at level k .
We define the depth of a forest is the maximum level number of all the nodes , the width of a forest is the maximum number of nodes at the same level.
Input
There’re several test cases. For each case, in the first line there are two integer numbers n and m (1≤n≤100, 0≤m≤100, m≤n*n) indicating the number of nodes and edges respectively , then m lines followed , for each line of these m lines there are two integer numbers a and b (1≤a,b≤n)indicating there’s an edge pointing from a to b. Nodes are represented by numbers between 1 and n .n=0 indicates end of input.
Output
For each case output one line of answer , if it’s not a forest , i.e. there’s at least one loop or two edges pointing to the same node, output “INVALID”(without quotation mark), otherwise output the depth and width of the forest, separated by a white space.
思路:由于题目要求合法的图应该 ①没有环 ②没有入度大于1的顶点——符合树的特点,因此,其实合法的输入其实是一堆树的集合,即为森林 (o(╯□╰)o 好吧,这点从题目名称就能看得出来)
解决方法:①判断是否会生成环最有效的方法是并查集 ②判断入度是否会大于一则可以简单的看要指向的结点是否有父节点
代码如下:
#include<stack>#include<iostream>#include<cmath>#include<string>#include<cstdio>#include<algorithm>#include<sstream>#include<iomanip>#include <cstring>#include <cstdlib>#include <vector>#include <map>#include <queue>#include <set>using namespace std;int father[110];//直接的父亲,例如 3→2→4 则father[4] == 2 而 father[2] == 3; //根的父亲定义为 0 int se_father[110];//用于并查集,存储的是所在树的根, //例如 3→2→4 则se_father[4] == 3 , se_father[2] == 3;int level[110];// i 在第level[i]层,定义根所在层为第一层int get_se_fa(int ch)//获取ch所在树的根,ch孤单一人的话则返回ch本身{ int fa = se_father[ch]; if (fa == 0) return ch; else return se_father[ch] = get_se_fa(fa); //这里是se_father[ch] = get_se_fa(fa) 而非 get_se_fa(fa),即为并查集的思想}int getLevel(int a){ if (level[a] != 0)//之前已经记录过,则直接返回 return level[a]; int fa = father[a]; if (fa == 0) //如果a是根,则标记level为1 return level[a] = 1; else return level[a] = getLevel(fa) + 1; //否则递归计算层数}int main(){ int n, m; while (cin >> n >> m, n) { memset(father, 0, sizeof(father)); memset(se_father, 0, sizeof(se_father)); memset(level, 0, sizeof(level)); int a, b; bool INVflag = false;//标记是否已经判定为"INVALID" for (int i = 0; i < m; i++) { cin >> a >> b; if (INVflag) continue; //a == b表示自己指向自己; get_se_fa(b) != b表示已经有结点指向b; //get_se_fa(a) == get_se_fa(b) 表示已经在同一树里 if (a == b || get_se_fa(b) != b || get_se_fa(a) == get_se_fa(b)) { INVflag = true; cout << "INVALID" << endl; continue;/*之所以用continue而不是break是因为要把输入处理完,才能进行 下一个test case*/ } father[b] = a;//标记b的直接父亲为a se_father[b] = get_se_fa(a);//将b所在树和a所在树合并,并查集思想 } if (!INVflag) { int width[110] = { 0 }; int max_depth = -9999; int max_width = -9999; for (int i = 1; i <= n; i++) { int t = getLevel(i); if (t > max_depth) // t 是否比当前最大深度还大 max_depth = t; width[t]++; //第 t 层的宽度加一 } for (int i = 0; i < 110; i++)//循环找出最大宽度 { if (width[i] > max_width) max_width = width[i]; } cout << max_depth-1 << " " << max_width << endl;//max_depth-1 是因为我在getlevel()里面把根的深度定为 1 } }}
- Sicily 1034. Forest
- Sicily 1034. Forest
- [sicily online]1034. Forest
- sicily 1034.Forest
- Sicily 1034. Forest
- sicily 1034. Forest
- Sicily---1034. Forest
- sicily-1034. Forest
- Sicily 1034 Forest(DFS)
- sicily 1034(Forest)
- Sicily 1034 Forest
- Sicily 1034 Forest
- #sicily#1004. Forest
- 1034. Forest
- 1034. Forest
- 1034. Forest
- 1034. Forest
- SOJ 1034. Forest
- 关于JAVA中的JNA
- css的权重
- 靠谱,是最低成本的社交方式
- 如何:click once把程序引用到的文件夹加入到“应用程序文件”列表里
- Swift3.0中文教程:2.基本运算符
- Sicily---1034. Forest
- javascript正则表达式总结(test|match|search|replace|split|exec)
- 设置maven可以自动下载jar包的sources以及JavaDoc
- C语言中函数参数入栈的顺序
- 自主导航nav_test.py代码分析
- 分布式一致性算法--raft
- 错误的单例模式(饱汉饿汉)
- 基本gulpfile.js
- 栅栏密码