• 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;
    }

     

  • 相关阅读:
    《构建之法(第三版)》第一章学习总结
    20189220余超 2019年密码与安全新技术讲座-课程总结报告
    学号20189220 2018-2019-2 《密码与安全新技术专题》第六周作业
    学号20189220余超 2018-2019-2 《密码与安全新技术专题》第七周作业
    20189200余超 2018-2019-2 移动平台应用开发实践作项目代码分析
    2018-2019-2学号20189220余超《移动平台应用程序开发实践》课程总结
    20189200余超 2018-2019-2 移动平台应用开发实践第十二周作业
    20189220余超 团队博客——阅读软件app
    20189200余超 2018-2019-2 移动平台应用开发实践第十一周作业
    20189200余超 2018-2019-2 移动平台应用开发实践第十周作业
  • 原文地址:https://www.cnblogs.com/shuitiangong/p/12340955.html
Copyright © 2020-2023  润新知