题意: 有n个顶点,m条边,选择最多n/2个顶点,在这个图每个顶尖顶点相邻(换句话说,一条边上的两个顶点)的至少选择一个的顶点。
思路: 奇偶染色法,对于相邻的两个顶点标记为不同的颜色,dfs遍历一遍即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=6e5+7;
struct EDGE
{
int next;
int to;
}edge[maxn];
int n,m,tot,head[maxn],vis[maxn],vs[300];
void add(int x,int y){
tot++;
edge[tot].next=head[x];
edge[tot].to=y;
head[x]=tot;
}
void dfs(int x,int dep){
vs[dep]++;
vis[x]=dep+1;
for(int i=head[x];i;i=edge[i].next){
if(vis[edge[i].to]) continue;
dfs(edge[i].to,dep^1);
}
}
int main(){
int t;scanf("%d",&t);
while(t--){
scanf("%d%d",&n,&m);
tot=0;
for(int i=0;i<=2*n+1;i++) head[i]=0;
for(int i=1;i<=m;i++) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y),add(y,x);
}
vs[0]=vs[1]=0;
for(int i=1;i<=n;i++) vis[i]=0;
dfs(1,1);
int now,cnt=0;
if(vs[0]<vs[1])cnt=vs[0], now=1;
else cnt=vs[1], now=2;
printf("%d\n",cnt);
for(int i=1;i<=n;i++) if(vis[i]==now) printf("%d ",i);puts("");
}
return 0;
}