虽然看着数据挺大的,但我看了好几个博客直接for的都AC了。
详细要注意的写在代码的注释里了。
#include<iostream>
#include<cstring>
#include<algorithm>
#pragma warning(disable:4996)
using namespace std;
const int NN = 10000 + 5, NF = 10000000 + 5;
int a[NF], num[NF];
int find(int x)
{
if (x == a[x] || a[x] == -1) return x;
a[x] = find(a[x]);
//这一步很重要,直接把x的根节点存储起来
//再次读取x的根节点的时候不需要再进行重复的递归查找
//这一个代码如果直接return find(a[x])的话TLE
return a[x];
}
int mer(int x, int y)
{
//这里数组a和num先在主函数用memset初始化,在有数据输入时才进行赋值
if (a[x] == -1) { a[x] = x; num[x] = 1;}
if (a[y] == -1) { a[y] = y; num[y] = 1;}
x = find(x);
y = find(y);
if (x != y)
{//判断是否在同一个集合中,否的话将两个集合合并,数量相加(和只要存储到根节点的位置即可)
a[y] = x;
num[x] += num[y];
}
return 1;
}
int main()
{
int m, mm, max0, x, y;
while (scanf("%d", &m) != EOF)
{
if (m == 0)
{//m为0时要输出1
printf("1\n");
continue;
}
mm = 0;
max0 = 0;
memset(a, -1, sizeof(a));
memset(num, -1, sizeof(num));
for (int i = 0; i < m; i++)
{
scanf("%d %d", &x, &y);
mer(x, y);
mm = max(max(x, y), mm);//记录城市最大数量,下面for的范围
}
for (int i = 1; i <= mm; i++)
{
max0 = max(max0, num[i]);
}
//cout << max0 << endl;
printf("%d\n", max0);
}
return 0;
}