聚会

这里写图片描述
这里写图片描述

把直接认识的人小于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;
}
原文地址:https://www.cnblogs.com/dfsac/p/7587794.html