Is It A Tree?

题目地址:

https://ac.nowcoder.com/acm/problem/105905

基本思路:

并查集维护生成树的过程,每次加边时判断一下是不是会产生环,
然后用存一下出现了的节点,最后判断一下这些出现了的节点是不是在一个联通块里面就行了。
注意空树的情况这时它也是树。

参考代码:

#include <iostream>
#include <string>
#include <list>
#include <map>
#include <set>
using namespace std;
#define IO std::ios::sync_with_stdio(false); cin.tie(0)
#define ll long long
#define SZ(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
#define rep(i, l, r) for (int i = l; i <= r; i++)
#define per(i, l, r) for (int i = l; i >= r; i--)
#define mset(s, _) memset(s, _, sizeof(s))
#define pb push_back
#define pii pair <int, int>
#define mp(a, b) make_pair(a, b)
#define INF 0x3f3f3f3f

const int maxn = 1e5 + 10;
int a,b,par[maxn];
set< int > st;
bool ok = true;
void init(){ rep(i,0,maxn - 1) par[i] = i; }
int find(int x){ return par[x] == x ? x : par[x] = find(par[x]); }
int main() {
  IO;
  init(); ok = true;
  int cas = 1;
  while (cin >> a >> b) {
    if (a == -1 && b == -1) break;
    if(a == 0 && b == 0) {
      set<int> tmp;
      for(set<int>::iterator it = st.begin() ; it != st.end() ; it++ ) tmp.insert(find(*it));
      if((ok && tmp.size() == 1) || st.empty()) cout << "Case " << cas++ << " is a tree." << '\n';
      else cout << "Case " << cas++ << " is not a tree." << '\n';
      init(); ok = true; st.clear();
      continue;
    }
    if(find(a) == find(b)) ok = false;
    else{
      par[find(a)] = find(b);
    }
    st.insert(a); st.insert(b);
  }
  return 0;
}