zoukankan      html  css  js  c++  java
  • 百练3383:Cell Phone Network

    传送门:http://bailian.openjudge.cn/practice/3383/

    【题解】

    题目就是最小支配集。

    学习了最小支配集的解法:

    树形dp(有空可以推一推)

    贪心:DFS遍历后逆DFS序进行处理,如果当前这个点不在支配集而且没和支配集连边,那么标记它父亲为支配集成员并处理父亲的父亲和自己(标为和支配集连边的)

    具体实现用一个数组记录支配集一个数组记录是否是支配集 or 连过边。

    # include <stdio.h>
    # include <string.h>
    # include <iostream>
    # include <algorithm>
    // # include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    const int M = 5e5 + 10;
    const int mod = 1e9+7;
    
    # define RG register
    # define ST static
    /*
    首先选择一点为树根,再按照深度优先遍历得到遍历序列,按照所得序列
    的反向序列的顺序进行贪心,对于一个即不属于支配集也不与支配集中的
    点相连的点来说,如果他的父节点不属于支配集,将其父节点加入到支配集
    */
    
    int n;
    int head[M], nxt[M], to[M], tot=0;
    bool s[M], is[M]; // have been covered yet(in set or connected with ... in set),  in set 
    
    inline void add(int u, int v) {
        ++tot; nxt[tot] = head[u];
        head[u] = tot; to[tot] = v;
    }
    inline void adde(int u, int v) {
        add(u, v), add(v, u);
    }
    
    int dfn[M], DFN=0, fa[M]; 
    inline void dfs(int x, int fat) {
        ++DFN; fa[x] = fat; 
        dfn[DFN] = x;
        for (int i=head[x]; i; i=nxt[i]) 
            if(to[i] != fat) dfs(to[i], x); 
    }
    
    int main() {
        while(cin >> n) { 
            memset(head, 0, sizeof head); tot = 0;
            DFN = 0; memset(s, 0, sizeof s); memset(is, 0, sizeof is);
            memset(fa, 0, sizeof fa); 
            for (int i=1, u, v; i<n; ++i) {
                scanf("%d%d", &u, &v);
                adde(u, v);  
            }
            dfs(1, 1);
            for (int i=n; i>=1; --i) {
                int x = dfn[i]; 
                if(!s[x]) {
                    if(!is[fa[x]]) is[fa[x]] = 1; 
                    s[x] = 1; s[fa[x]] = 1; s[fa[fa[x]]] = 1;
                }
            }
            int ans = 0;
            for (int i=1; i<=n; ++i) ans += is[i]; 
            if(n == 1) puts("1");
            else printf("%d
    ", ans); 
        }
        return 0;
    }
    View Code
  • 相关阅读:
    Word Search
    Subsets
    Combinations
    Search a 2D Matrix
    求比正整数N大的最小正整数M,且M与N的二进制表示中有相同数目的1
    Set Matrix Zeroes
    Unity学习笔记—— 常用脚本函数
    学习 各个数据结构
    unity调用 安卓相册
    设置 相机跟随 主角及视角 滑动
  • 原文地址:https://www.cnblogs.com/galaxies/p/bailian3383.html
Copyright © 2011-2022 走看看