直接做,如果依次删除度数小于d的点,然后求最后剩下的点中的最大的联通块。
#include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<iostream> #include<algorithm> #define maxn 500010 using namespace std; int to[maxn],next[maxn],d[maxn],vis[maxn],del[maxn],head[maxn]; int n,m,num,t,ans,top,sum; int q[maxn],s[maxn],cnt[maxn]; void addedge(int x,int y) { num++;to[num]=y;next[num]=head[x];head[x]=num;d[y]++; } void dfs(int x) { vis[x]=1;s[++top]=x;sum++; for (int p=head[x];p;p=next[p]) if (!del[to[p]] && !vis[to[p]]) dfs(to[p]); } int main() { scanf("%d%d%d",&n,&m,&t); for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); addedge(x,y);addedge(y,x); } int l=0,r=0; for (int i=1;i<=n;i++) if (d[i]<t) q[++r]=i,del[i]=1; while (l<r) { int x=q[++l]; for (int p=head[x];p;p=next[p]) if (!del[to[p]]) { d[to[p]]--; if (d[to[p]]<t) q[++r]=to[p],del[to[p]]=1; } } for (int i=1;i<=n;i++) if (!del[i] && !vis[i]) {sum=0;top=0;dfs(i);if (sum>ans) {ans=sum;for (int i=1;i<=sum;i++) cnt[i]=s[i];}} if (ans) { printf("%d\n",ans); sort(cnt+1,cnt+ans+1); for (int i=1;i<=ans;i++) printf("%d ",cnt[i]); } else printf("NIE\n"); return 0; }