Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // 并查集数据结构
- // 对动态连接图可能的操作
- // 1) 查询节点属于的组
- // 2)判断两个节点是否属于同一个组
- // 3)连接两个节点,使之属于同一个组
- // 4)获取组的数目
- // 树数据结构容易出现极端情况,在建树的过程中,树的最终形态严重依赖于输入数据本身的性质
- // 判断一个无向图是树的条件是连通图,且所有点的入度小于等于1
- // 并查集的实现
- #include <memory.h>
- #include <iostream>
- #include <stdio.h>
- using namespace std;
- class UF
- {
- private:
- int * id;// 保存其父节点,当是root节点时 id[p] = p;
- int count; // 组个数
- int * sz;
- public:
- UF(int n)
- {
- id = new int [n];
- for(int i=0; i< n; i++)
- id[i] = i;
- sz = new int [n];
- for(int i=0; i< n; i++)
- sz[i] = 1;
- count = n;
- }
- // 返回组的个数
- int Count()
- {
- return count;
- }
- // 判断是否连通
- bool is_connected(int p, int q)
- {
- return find(p) == find(q);
- }
- // find 查找节点的组ID
- int find(int p)
- {
- while(p != id[p])
- {
- id[p] = id[id[p]];
- p = id[p];
- }
- return p;
- }
- // 合并连接两个组
- void Union(int p, int q)
- {
- int pRoot = find(p);
- int qRoot = find(q);
- //cout << "pRoot " <<pRoot << "\t" << "qRoot " << qRoot <<
- // endl;
- if(pRoot == qRoot)
- return;
- // 将小树作为大树的子树
- if (sz[pRoot] < sz[qRoot])
- {
- id[pRoot] = qRoot;
- sz[qRoot] += sz[pRoot];
- }
- else
- {
- id[qRoot] = pRoot;
- sz[pRoot] += sz[qRoot];
- }
- count --;
- }
- };
- int main()
- {
- //freopen("hiho_1322.data","r",stdin);
- int t;
- cin >>t;
- for(int i=0; i< t;i++)
- {
- int N, M;
- cin >> N >> M;
- UF uf(N);
- int * in = new int[N];
- memset(in,0,sizeof(int) * N);
- bool is_tree = true;
- for(int k = 0; k < M; k++)
- {
- int s,e;
- cin >> s >> e;
- uf.Union(s-1,e-1);
- in[e-1] ++;
- if (in[e-1] > 1)
- is_tree = false;
- }
- if (uf.Count() > 1)
- is_tree = false;
- if (is_tree)
- cout << "YES" << endl;
- else
- cout << "NO" << endl;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement