题目大意:
有一个图G,G中有n个顶点。图G中把点分为两部分,其中一部分是A,另一部分是B,且B中每个顶点都和A中的顶点相连,问应该怎么分A,B。注意A,B两部分的顶点不能超过
题解:
我们注意到BFS遍历有一个特点就是:每一层都和另外一层相连,通过这个特点,我们可以选择BFS中的奇数层或者偶数层,取决于奇数层还是偶数层具有较少的总顶点数,可以这样选取的主要原因在于不可能 奇数层或者偶数层同时超过,可以用反证法证明。
个人总结:没做出来,根本原因还是不了解BFS有这个性质,只能吃一蛰长一智咯
AC代码:
#include <bits/stdc++.h>
#define EVEN 0
#define ODD 1
#define UNVISITED 0
#define VISITED 1
using namespace std;
vector<vector<pair<int,int>>> gra;
int main(){
int cas;
cin>>cas;
for(int ca=0;ca<cas;ca++){
int n,m;
cin>>n>>m;
gra=vector<vector<pair<int,int>>>(n);
for(int i=0;i<m;i++){
int fir;int las;
cin>>fir>>las;
fir-=1;
las-=1;
gra[fir].emplace_back(las,0);
gra[las].emplace_back(fir,0);
}
vector<int> count[2];
int dist[n];
int flag[n]={0};
queue<int> q;
int u=0;
q.push(u);
flag[u]=VISITED;
dist[u]=0;
while(!q.empty()){
int u=q.front();q.pop();
if(dist[u]%2==0)count[EVEN].push_back(u);
else count[ODD].push_back(u);
for(int i=0;i<(int)gra[u].size();i++){
int nx=gra[u][i].first;
if(flag[nx]==UNVISITED){
flag[nx]=VISITED;
dist[nx]=dist[u]+1;
q.push(nx);
}
}
}
int szODD=count[ODD].size();
int szEVEN=count[EVEN].size();
if(szODD<szEVEN){
cout<<szODD<<endl;
for(int i=0;i<(int)count[ODD].size();i++){
if(i)cout<<" ";
cout<<count[ODD][i]+1;
}
cout<<endl;
}else{
cout<<szEVEN<<endl;
for(int i=0;i<(int)count[EVEN].size();i++){
if(i)cout<<" ";
cout<<count[EVEN][i]+1;
}
cout<<endl;
}
}
return 0;
}