Topic Description Narration:
If there is a known n person and M-to-friend relationship (stored in the number R). Let's say that two people are direct or indirect friends (Friends of friends ... )。 Think they belong to the same circle of friends, please tap the code to find out how many of these n people have a common circle of friends.
if: n = 5. m = 3, r = {{1, 2}, {2, 3}, {4, 5}}, representing 5 people. 1 and 2 are friends, 2 and 3 are friends, 4 and 5 are friends. Then 1, 2, 3 belong to a circle of friends, 4, 5 belong to a circle of friends, the result is 2 friends circle.
Input:
The input includes multiple test examples. The first line of each test example consists of two positive integers n, M. 1=<n,m<=100000
.
Then there's M-line. Enter a number of two people per line f,t(1=<f,t<=n)
, indicating that F and T are friends. When n is 0 o'clock, the input ends and the use case is not processed.
Output:
Each of the corresponding test examples, output in this n individuals in a common how many circle of friends.
Example input:
5 3
1 2
2 3
4 5
3 3
1 2
1 3
2 3
0
Example output:
2
1
Thinking of solving problems
Use forests made up of trees to solve problems. Each tree represents a circle of friends. Building two array IDs and Sz,id[x] represents the root node of x, Sz[x] represents the number of nodes in the tree with x as the root node.
- Initialize: For i = 1 to Personcount, id[i] = i, sz[i] = 1;
- Infer an input set of relationships to see if two nodes are in the same tree (the root node is the same). If different, the smaller tree is merged into a larger tree (the root node of the decimal root node is set to the root node of the tree). At the same time, the number of nodes of the tree is set to the sum of tree nodes and small tree nodes.
(for lookup functions.) To speed up the query, you can compress the path and set the node's parent to its grandfather nodes.
More specific ideas: http://blog.csdn.net/dm_vincent/article/details/7655764
Implementation code
#include <iostream>using namespace STD;classuf{ Public: UF (intN) {id =New int[n]; SZ =New int[n]; Count = N-1; for(inti =0; I < n; i++) {Id[i] = i; Sz[i] =1; } }intGetCount () {returnCount }intFindset (intN) { while(n! = Id[n]) {Id[n] = id[id[n]]; n = id[n]; }returnN }voidUnionset (intXintY) {intDX = Findset (x);intdy = Findset (y);if(dx! = dy) {count--;if(SZ[DX] > Sz[dy]) {Id[dy] = dx; SZ[DX] + = Sz[dy]; }Else{ID[DX] = dy; Sz[dy] + = SZ[DX]; }}} ~uf () {Delete[] ID;Delete[] sz; }Private:int*id;int*sz;intCount;};intMain () {intPersoncount; while(Cin>>personcount, Personcount) {UF *uf =NewUF (Personcount +1);intRelationcount;Cin>>relationCount;intx, y; for(inti =0; i < Relationcount; i++) {Cin>>x>>y; Uf->unionset (x, y); }cout<<uf->getcount () <<endl;Deleteuf }return 0;}
[Xiaomi] and check set