CodeForces - 1176E - Cover it!

题目链接: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;
}

 

posted @ 2020-02-21 12:41  shuitiangong  阅读(201)  评论(0编辑  收藏  举报