題目大意:給定多組數據,每組數據以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; }