题目链接:https://vjudge.net/problem/CodeForces-1176E
题目大意就是让你最多选n/2个点(向下取整)使得每个点旁边最少有一个被选中的点,因为最多可以选n/2个点,所以我们把这些点分成两种交替出现的状态,肯定必有一种状态满足题意。
1.通过判断子节点与父节点来选取数量较少的一边: #include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define zero(a) memset(a, 0, sizeof(a)) #define INF(a) memset(a, 0x3f, sizeof(a)) #define IOS ios::sync_with_stdio(false) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<int, int> P; typedef pair<double, int> P2; const double pi = acos(-1.0); const double eps = 1e-7; const ll MOD = 1000000007LL; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const double EULC = 0.5772156649015328; const int NIL = -1; template<typename T> void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } const int maxn = 2e5+10; int vis[maxn]; vector<int> eage[maxn], odd, even; void dfs(int u, int flag) { if (flag && !vis[u]) odd.push_back(u); else even.push_back(u); vis[u] = true; for (auto node : eage[u]) if (!vis[node]) dfs(node, !flag); } int main(void) { int t; scanf("%d", &t); while(t--) { int n, m; scanf("%d%d", &n, &m); for (int i = 0, u, v; i<m; ++i) { scanf("%d%d", &u, &v); eage[u].push_back(v); eage[v].push_back(u); dfs(1, 1); int size1 = odd.size(), size2 = even.size(); printf("%d\n", min(size1, size2)); if (size1 < size2) for (int i = 0; i<size1; ++i) printf(i == size1-1 ? "%d\n" : "%d ", odd[i]); else for (int i = 0; i<size2; ++i) printf(i == size2-1 ? "%d\n" : "%d ", even[i]); for (int i = 0; i<=n; ++i) eage[i].clear(), vis[i] = 0; odd.clear(), even.clear(); } return 0; 2.通过判断与某个结点距离的奇偶性 #include<set> #include<map> #include<stack> #include<queue> #include<cmath> #include<cstdio> #include<cctype> #include<string> #include<vector> #include<climits> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #define endl '\n' #define max(a, b) (a > b ? a : b) #define min(a, b) (a < b ? a : b) #define zero(a) memset(a, 0, sizeof(a)) #define INF(a) memset(a, 0x3f, sizeof(a)) #define IOS ios::sync_with_stdio(false) #define _test printf("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n") using namespace std; typedef long long ll; typedef pair<ll, ll> P; typedef pair<ll, ll> P2; const double pi = acos(-1.0); const double eps = 1e-7; const ll MOD = 1000000007LL; const int INF = 0x3f3f3f3f; const int _NAN = -0x3f3f3f3f; const double EULC = 0.5772156649015328; const int NIL = -1; template<typename T> void read(T &x){ x = 0;char ch = getchar();ll f = 1; while(!isdigit(ch)){if(ch == '-')f*=-1;ch=getchar();} while(isdigit(ch)){x = x*10+ch-48;ch=getchar();}x*=f; } const int maxn = 2e5+10; int d[maxn]; vector<int> odd, even, eage[maxn]; void bfs() { queue<int> qe; d[1] = 0; qe.push(1); even.push_back(1); while(!qe.empty()) { int t = qe.front(); qe.pop(); for (auto to : eage[t]) if (d[to] == INF) { d[to] = d[t]+1; qe.push(to); if (d[to]&1) odd.push_back(to); else even.push_back(to); } } } int main(void) { int t; scanf("%d", &t); while(t--) { int n, m; scanf("%d%d", &n, &m); for (int i = 0; i<n+10; ++i) d[i] = INF; for (int i = 0, u, v; i<m; ++i) { scanf("%d%d", &u, &v); eage[u].push_back(v); eage[v].push_back(u); } bfs(); int size1 = odd.size(), size2 = even.size(); printf("%d\n", min(size1, size2)); if (size1 < size2) for (int i = 0; i<size1; ++i) printf(i == size1-1 ? "%d\n" : "%d ", odd[i]); else for (int i = 0; i<size2; ++i) printf(i == size2-1 ? "%d\n" : "%d ", even[i]); for (int i = 0; i<=n; ++i) eage[i].clear(); odd.clear(), even.clear(); } return 0; }