把直接认识的人小于d的人删去,然后染色,找最大值就可以了。
一开始删点时,将已经删过的点重复入队,把它的临接点的du多次重复地减,导致出错。
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
#include<cmath>
#include<cstdio>
#define N 200009
using namespace std;
int n,m,d;
int head[N],nxt[2*N],to[2*N],du[N],tot,q[10*N],l,r;
int color[N],color_num,cnt[N];
bool f[N];
void add(int x,int y)
{
to[++tot]=y;
nxt[tot]=head[x];
head[x]=tot;
}
void dfs(int x)
{
color[x]=color_num;
f[x]=1;
for(int i=head[x];i;i=nxt[i])
{
if(du[to[i]]>=d&&!color[to[i]])
{
dfs(to[i]);
}
}
}
int main()
{
scanf("%d%d%d",&n,&m,&d);
for(int i=1;i<=m;i++)
{
int a,b;
scanf("%d%d",&a,&b);
add(a,b),add(b,a);
du[a]++;du[b]++;
}
for(int i=1;i<=n;i++) if(du[i]<d) q[++r]=i,f[i]=1;
while(l<=r)
{
int x=q[++l];
for(int i=head[x];i;i=nxt[i])
{
du[to[i]]--;
if(du[to[i]]<d&&!f[to[i]]) q[++r]=to[i],f[to[i]]=1;//f数组做标记!!
}
}
for(int i=1;i<=n;i++)
{
if(!color[i]&&!f[i]) ++color_num,dfs(i);
}
for(int i=1;i<=n;i++) cnt[color[i]]++;
int maxn=0,C;
for(int i=1;i<=color_num;i++) maxn=max(maxn,cnt[i]);
printf("%d
",maxn);
for(int i=1;i<=n;i++)
if(cnt[color[i]]==maxn)
{
C=color[i];
break;
}
for(int i=1;i<=n;i++)
if(color[i]==C) printf("%d ",i);
return 0;
}