HDU-1325(Is it a tree?) 並查集

題目大意:給定多組數據,每組數據以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;
}
相關文章
相關標籤/搜索