基础的并查集练习,可以水过。
quick find :
直接循环改数,时间复杂度为N方。
#include <iostream>
using namespace std;
int id[1005] ;
void unionroot(int a, int b, int N );
int main()
{
int T=0 ;
cin >> T ;
while(T--)
{
int N = 0,M = 0, num = 0;
int a , b ;
cin >> N >> M ;
for(int i=1 ; i<=N ; i++)
id[i] = i;
while(M--)
{
cin >> a >> b ;
unionroot(a, b, N);
}
for(int i=1 ; i<=N ; i++)
if(i==id[i])
num++;
cout << num << endl ;
}
return 0;
}
void unionroot(int a, int b, int N )
{
int idp = id[a] ;
int idq = id[b] ;
for(int i = 1 ; i <= N ; i++)
if(id[i]==idp)
id[i] = idq ;
}
#include <iostream>
using namespace std;
int id[1005] ;
void unionroot(int a, int b, int N );
int findroot(int a);
int main()
{
int T=0 ;
cin >> T ;
while(T--)
{
int N = 0,M = 0, num = 0;
int a , b ;
cin >> N >> M ;
for(int i=1 ; i<=N ; i++)
id[i] = i;
while(M--)
{
cin >> a >> b ;
unionroot(a, b, N);
}
for(int i=1 ; i<=N ; i++)
if(i==id[i])
num++;
cout << num << endl ;
}
return 0;
}
void unionroot(int a, int b, int N )
{
int idp = findroot(a) ;
int idq = findroot(b) ;
id[idp] = idq ;
}
int findroot(int a)
{
while(a!=id[a])
{
a = id[a] ;
}
return a ;
}
weighted quick union :
#include <iostream>
#include <string.h>
using namespace std;
int id[1005] ;
int weight[1005] ;
void unionroot(int a, int b, int N );
int findroot(int a);
int main()
{
int T=0 ;
cin >> T ;
while(T--)
{
int N = 0,M = 0, num = 0;
int a , b ;
cin >> N >> M ;
memset(weight, 1, sizeof(int));
for(int i=1 ; i<=N ; i++)
id[i] = i;
while(M--)
{
cin >> a >> b ;
unionroot(a, b, N);
}
for(int i=1 ; i<=N ; i++)
if(i==id[i])
num++;
cout << num << endl ;
}
return 0;
}
void unionroot(int a, int b, int N )
{
int idp = findroot(a) ;
int idq = findroot(b) ;
if(weight[idq] <= weight[idp])
{
id[idp] = idq ;
weight[idq] += weight[idp] ;
}
else
{
id[idq] = idp ;
weight[idp] += weight[idq] ;
}
}
int findroot(int a)
{
while(a!=id[a])
{
a = id[a] ;
}
return a ;
}
path compression:只在寻找根节点的同时加了一句提升根节点。
#include <iostream>
#include <string.h>
using namespace std;
int id[1005] ;
int weight[1005] ;
void unionroot(int a, int b, int N );
int findroot(int a);
int main()
{
int T=0 ;
cin >> T ;
while(T--)
{
int N = 0,M = 0, num = 0;
int a , b ;
cin >> N >> M ;
memset(weight, 1, sizeof(int));
for(int i=1 ; i<=N ; i++)
id[i] = i;
while(M--)
{
cin >> a >> b ;
unionroot(a, b, N);
}
for(int i=1 ; i<=N ; i++)
if(i==id[i])
num++;
cout << num << endl ;
}
return 0;
}
void unionroot(int a, int b, int N )
{
int idp = findroot(a) ;
int idq = findroot(b) ;
if(weight[idq] <= weight[idp])
{
id[idp] = idq ;
weight[idq] += weight[idp] ;
}
else
{
id[idq] = idp ;
weight[idp] += weight[idq] ;
}
}
int findroot(int a)
{
while(a!=id[a])
{
id[a] = id[id[a]];
a = id[a] ;
}
return a ;
}