题目大意:给定多组数据,每组数据以0 0结尾,-1 -1结束输入。经过已知节点信息判断是否是一棵树ios
解题思路:看边和节点的关系,有无造成环;看是否是森林,即入度为0的根只有一个;除根节点外的每一个节点入度不得超过1;ide
实现代码:测试
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<cassert> #include<complex>//real().imag(). #include<cctype> #include<algorithm> #include<iomanip> #include<stack> #include<queue> #include<list> #include<map> #include<set> #include<deque> #include<string> #include<utility> #include<iterator> #define pii pair<int,int> #define make_pair mp using namespace std; typedef long long ll; const int N = 100005;//题目没给具体数据,瞎搞的 int root = 0;//根的数量 int indgree[N], f[N]; //入度 bool vis[N];//是否访问 int flag = 1;//决定结果 int cnt = 1;//case数量 int side = 0;//边的数量,用来判断空树 void init()//初始化 { root = 0;//根数为0 side = 0;//边数为0 flag = 1;//知足条件 memset(f, -1, sizeof(f));//初始化根节点为-1 memset(vis, false, sizeof(vis));//初始化为未访问 memset(indgree, 0, sizeof(indgree));//初始化每一个节点入度为0 } int U_find(int x)//朴素查找,记得根节点默认是-1 { while (f[x] != -1) { x = f[x]; } return x; } void U_merge(int x, int y)//把一对数的前者做为后者的根 { int xx = U_find(x); int yy = U_find(y); if (yy != xx) { f[yy] = xx; } } int main() { int a, b; init();//开局初始化 while (cin >> a >> b)//循环输入每一对数 { side++;//由于插入一对,边数+1 if (a == -1 && b == -1)//退出条件 break; U_merge(a, b);//没退出的话,合并 vis[a] = vis[b] = true;//标记访问过的节点 indgree[b]++;//由于a是b的根,因此b的入度+1 if (a == 0 && b == 0)//输入0 0时 { if (side == 1)//若是只有一条边,说明是空树 { cout << "Case " << cnt++ << " is a tree." << endl; } else { for (int i = 1; i <= N; ++i)//不然开始遍历全部节点 { if (vis[i])//遇到访问过的节点 { if (indgree[i] >= 2)//入度>=2的话,说明不知足题意 { flag = 0;//更易flag } if (indgree[i] == 0)//入度为0,说明该节点是树根 { root++; } } } if (root == 1 && flag == 1)//知足条件同时根为1 { cout << "Case " << cnt++ << " is a tree." << endl; } else { cout << "Case " << cnt++ << " is not a tree." << endl; } } init();//再次初始化迎接下一组测试数据 } } return 0; }