E. Cover it!(黑白染色问题)

传送门哈哈传递哈斯防火墙

(因为图联通,我们任取一点开始遍历)

(比如从点1开始,那么假设1涂色)

(那么和1相邻的不上色,相邻的相邻上色)

(但这样答案可能超过n/2.)

(那我们对颜色取反,上色的都不上色,不上色的都上色)

(效果相同,但一定小于n/2了)

#include <bits/stdc++.h>
using namespace std;
const int maxn=4e5+10;
int top,vis[maxn],t,n,m,color[maxn];
struct p{
	int to,nxt;
}d[maxn];int head[maxn],cnt=1;
void add(int u,int v){
	d[cnt].to=v,d[cnt].nxt=head[u],head[u]=cnt++;
}
void dfs(int now,int se)
{
	color[now]=se;
	if(se)	top++;
	for(int i=head[now];i;i=d[i].nxt)
	{
		int v=d[i].to;
		if(vis[v])	continue;
		vis[v]=1;
		dfs(v,se^1);
	}
}
void print_one(){
	cout<<top<<endl;
	for(int i=1;i<=n;i++)	if(color[i])	printf("%d ",i);
}
void print_zero(){
	cout<<n-top<<endl;
	for(int i=1;i<=n;i++)	if(color[i]==0)	printf("%d ",i);
}
int main()
{
	cin>>t;
	while(t--)
	{
		cin>>n>>m;
		for(int i=1;i<=m;i++)
		{
			int l,r;
			scanf("%d%d",&l,&r);
			add(l,r),add(r,l);
		}
		vis[1]=1;
		dfs(1,0);
		if(top<=n/2)	print_one();
		else	print_zero();
		cout<<endl;
		for(int i=1;i<=n;i++)	vis[i]=head[i]=color[i]=0;
		top=0,cnt=1;
	}
}