王先生选择了一个足够大的房间来容纳这些男孩。那个没有被选中的男孩必须立即离开房间。房间里有10000万男孩,从一开始的1到10000万。在王的选择之后,任何两个还在这个房间里的人都应该是朋友(直接的或间接的),否则就只剩下一个男孩了。考虑到所有直接的朋友对,你应该决定最好的方式。
输入
输入的第一行包含一个整数n (0≤n≤100 000)——直接friend-pairs的数量。下面的n行每一行都包含一对数字a和B,用一个空格隔开,这表明a和B是直接的朋友。(≤1≠B A、B≤10000000)
输出
一行中的输出恰好包含一个整数,该整数等于王先生可能保留的最大男孩数。
模板,可以合并的时候用cnt数组维护。
也可以统计答案的时候直接看是哪个组的 这个组++。
#include <cstdio>
#include <cstring>
#define m(a,b) memset(a,b,sizeof a)
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int N=100005;
const int INF=0x3f3f3f3f;
int f[N],cnt[N];
int vis[N];
int seek(int x)
{
int ances=x;
while(ances!=f[ances])
ances=f[ances];
int father=x;
while(x!=ances)
{
father=f[x];
f[x]=ances;
x=father;
}
return ances;
}
int main()
{
int m;
while(~scanf("%d",&m))
{
if(!m)
{
printf("1\n");
continue;
}
m(vis,0),m(cnt,0);
for(int i=1;i<=N;i++)
f[i]=i;
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
vis[a]=1,vis[b]=1;
int ra=seek(a),rb=seek(b);
if(ra!=rb)
f[ra]=rb;
}
int maxn=0;
for(int i=1;i<=N;++i)
{
if(!vis[i])
continue;
f[i]=seek(i);
++cnt[f[i]];
maxn=maxn>cnt[f[i]]?maxn:cnt[f[i]]; //也可以放在最后把每个祖先的值找最大的
}
printf("%d\n",maxn);
}
}
#include <cstdio>
#include <cstring>
#define m(a,b) memset(a,b,sizeof a)
#define inf 0x3f3f3f3f
typedef long long ll;
using namespace std;
const int N=100005;
const int INF=0x3f3f3f3f;
int f[N],cnt[N];
int vis[N];
int seek(int x)
{
int ances=x;
while(ances!=f[ances])
ances=f[ances];
int father=x;
while(x!=ances)
{
father=f[x];
f[x]=ances;
x=father;
}
return ances;
}
int main()
{
int m;
while(~scanf("%d",&m))
{
if(!m)
{
printf("1\n");
continue;
}
m(vis,0),m(cnt,0);
for(int i=1;i<=N;i++)
f[i]=i,cnt[i]=1;
int a,b;
while(m--)
{
scanf("%d%d",&a,&b);
vis[a]=1,vis[b]=1;
int ra=seek(a),rb=seek(b);
if(ra!=rb)
{
f[ra]=rb;
cnt[rb]+=cnt[ra];
}
}
int maxn=0;
for(int i=1;i<=N;++i)
{
if(!vis[i]) //vis标记的并不是祖先 而是出先过的数。
continue;
maxn=maxn>cnt[i]?maxn:cnt[i];
}
printf("%d\n",maxn);
}
}