按秩和父节点优化的并查集模板搞就行了。
刚开始代码一直runtime error ,后来把没个组的输入中的数组移除掉就好了
AC代码
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define in(x) scanf("%d",&x)
int p[30005];
int rank[30005];
int n,m;
int tag;
void build(){
for(int i = 0;i < n;i++){
p[i] = i;
}
}
int find(int x){
if(p[x] != x){
p[x] = find(p[x]);
}
return p[x];
}
void uni(int x,int y){
// p[find(y)]=find(x);
x = find(x),y = find(y);
if(rank[x] < rank[y]){
p[x] = y;
}
else {
p[y] = x;
if(rank[x] == rank[y]){
rank[x]++;
}
}
}
int main(){
while(~in(n)&&~in(m)&&(n||m)){
memset(p,-1,sizeof(p));
memset(rank,0,sizeof(rank));
build();
for(int i=1;i<=m;i++){
int k;
in(k);
int a;
in(a);
for(int j=1;j<k;j++){
int b;
in(b);
uni(b,a);
a=b;
}
}
tag=find(0);
int cnt=0;
for(int i=0;i<n;i++){
if(find(i)==tag){
cnt++;
}
}
cout<<cnt<<endl;
}
return 0;
}
一开始的runtime error代码 (代码问题应该是出在new那段,但实在想不出来是为什么,有谁能帮我想明白吗)
#include <iostream>
#include <stdio.h>
#include <cmath>
#include <cstring>
#include <algorithm>
using namespace std;
#define in(x) scanf("%d",&x)
int p[30005];
int rank[30005];
int n,m;
int tag;
void build(){
for(int i = 0;i < n;i++){
p[i] = i;
}
}
int find(int x){
if(p[x] != x){
p[x] = find(p[x]);
}
return p[x];
}
void uni(int x,int y){
// p[find(y)]=find(x);
x = find(x),y = find(y);
if(rank[x] < rank[y]){
p[x] = y;
}
else {
p[y] = x;
if(rank[x] == rank[y]){
rank[x]++;
}
}
}
int main(){
while(~in(n)&&~in(m)&&(n||m)){
memset(p,-1,sizeof(p));
memset(rank,0,sizeof(rank));
build();
for(int i=1;i<=m;i++){
int k;
in(k);
int *kk=new int(k);
for(int j=0;j<k;j++){
in(kk[j]);
if(j){
uni(kk[j],kk[j-1]);
}
}
}
tag=find(0);
int cnt=0;
for(int i=0;i<n;i++){
if(find(i)==tag){
cnt++;
}
}
cout<<cnt<<endl;
}
return 0;
}