其实这道题是个水题,我当初看一眼就想出了正解,:记录每个点的度数,若果小于题目要求的度数d,则删去这个点以及这个点连的边。继续,知道图中的点全部符合要求为止,最后在遍历整个剩下的图,从中找一个最大连通块即可。
代码如下:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 200100;
int n,m,d;
int head[maxn],cnt=0;
int deg[maxn],vis[maxn],used[maxn];
struct edge
{
int to,pre;
}e[maxn*2];
int ans=0,final=-1;
int q[maxn],tot=0,id;
inline void read(int &x)
{
int f=1;x=0;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){x=x*10+s-'0';s=getchar();}
x*=f;
}
inline void add(int x,int y)
{
e[++cnt].pre=head[x];
e[cnt].to=y;
head[x]=cnt;
}
void del(int x)
{
vis[x]=1;
used[x]=1;
for(int i=head[x];i;i=e[i].pre)
{
int y=e[i].to;
if(deg[y]-1>=d)
{
deg[y]--;
continue;
}
if(vis[y]) continue;
del(y);
}
}
void dfs(int x)
{
vis[x]=1;
ans++;
for(int i=head[x];i;i=e[i].pre)
{
int y=e[i].to;
if(vis[y]) continue;
dfs(y);
}
}
void dfs1(int x)
{
q[++tot]=x;
used[x]=1;
for(int i=head[x];i;i=e[i].pre)
{
int y=e[i].to;
if(used[y]) continue;
dfs1(y);
}
}
int main()
{
freopen("party.in","r",stdin);
freopen("party.out","w",stdout);
read(n);read(m);read(d);
for(int i=1;i<=m;++i)
{
int x,y;
read(x);read(y);
add(x,y);
add(y,x);
deg[x]++;
deg[y]++;
}
for(int i=1;i<=n;++i)
{
if(deg[i]<d&&!vis[i])
del(i);
}
for(int i=1;i<=n;++i)
{
if(vis[i]) continue;
ans=0;
dfs(i);
if(ans>final)
{
final=ans;
id=i;
}
}
dfs1(id);
printf("%d\n",final);
sort(q+1,q+1+tot);
for(int i=1;i<=tot;++i)
printf("%d ",q[i]);
return 0;
}