题目
题意: 给你一张n个点m条边的连通图,无自环和重边。输出k和k个点的编号。 k<=[n/2]。使得没被选的点一定会和这k个点里至少一个有边相连。
思路: 直接将图生成一棵树,第一种涂色方法是将奇数层全涂色,若这种方法涂色节点数大于⌊n/2⌋,那么将偶数层全涂色肯定可行。
#include<bits/stdc++.h>
#define m(a,b) memset(a,b,sizeof a)
using namespace std;
const int N=2e5+5;
struct Edge{int to,nex;}edge[N<<1];int head[N],tot;
inline void add(int from,int to){
edge[++tot]=(Edge){to,head[from]},head[from]=tot;
edge[++tot]=(Edge){from,head[to]},head[to]=tot;
}
int cnt[2],vis[N];
void dfs(int x,int o){
vis[x]=o,++cnt[o];
for(int i=head[x];i;i=edge[i].nex){
int y=edge[i].to;
if(vis[y]==-1) dfs(y,o^1);
}
}
int main(){
int T;scanf("%d",&T);
while(T--){
int n,m;scanf("%d%d",&n,&m);
for(int i=1;i<=n;++i) head[i]=0,vis[i]=-1;
tot=0;cnt[0]=cnt[1]=0;
for(int i=1,x,y;i<=m;++i) scanf("%d%d",&x,&y),add(x,y);
dfs(1,0);
int anscnt=cnt[0],dex=0;
if(cnt[0]>cnt[1]) anscnt=cnt[1],dex=1;
printf("%d\n",anscnt);
for(int i=1;i<=n;++i) if(vis[i]==dex) printf("%d ",i);
puts("");
}
}