题目链接:https://cn.vjudge.net/problem/ZOJ-4109
题解:每个独立集先取最小的,然后像拓扑排序那样进行即可,注意的一点就是遇到一个点,这个点即可加入到优先队列中,这个跑独立集的时候bfs跑,dfs爆了
#include<bits/stdc++.h>
using namespace std;
const int N=2e6+10;
int n,m;
int vis[N];
int book[N];
struct node{
int to,nex;
}e[N*2];
int ans[N],cnt;
int head[N],len;
void dfs(int u)
{
int to;
queue<int> q;
q.push(u);
while(!q.empty())
{
to=q.front();q.pop();
for(int i=head[to];i!=-1;i=e[i].nex)
{
to=e[i].to;
if(vis[to]) continue;
vis[to]=1;
q.push(to);
}
}
}
void add(int x,int y)
{
e[len].to=y;
e[len].nex=head[x];
head[x]=len++;
}
priority_queue<int,vector<int>,greater<int> > q;
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
{
vis[i]=0;
book[i]=0;
head[i]=-1;
}
cnt=0;len=0;
int x,y;
for(int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
add(x,y);
add(y,x);
}
int num=0;
for(int i=1;i<=n;i++)
{
if(vis[i]) continue;
vis[i]=1;
dfs(i);
num++;
book[i]=1;
q.push(i);
}
int now;
int l,to;
while(!q.empty())
{
now=q.top();q.pop();
ans[++cnt]=now;
for(int i=head[now];i!=-1;i=e[i].nex)
{
to=e[i].to;
if(book[to]==0)
{
book[to]=1;
q.push(to);
}
}
}
printf("%d\n",num);
for(int i=1;i<=n;i++)
{
printf("%d",ans[i]);
if(i!=n) printf(" ");
else printf("\n");
}
}
return 0;
}