zoukankan      html  css  js  c++  java
  • CCPC 2016 杭州 E. Master of Subgraph(点分治+bitset优化DP)

    题目链接:http://acm.hdu.edu.cn/downloads/CCPC2018-Hangzhou-ProblemSet.pdf

    题意:给定一棵有 n 个结点的树和一个数 m,对于 i ∈ [1,m] 问是否存在一个子图结点的权值和为 i 。

    题解:一个显然的思路是树上做背包,但显然会 T。要遍历全部子图,考虑进行点分治,然后合并的时候用 bitset 优化背包,时间复杂度O(nmlogn / 64),且时限给了 8s。

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 #define ll long long
     4 #define ull unsigned long long
     5 #define mst(a,b) memset((a),(b),sizeof(a))
     6 #define mp(a,b) make_pair(a,b)
     7 #define pi acos(-1)
     8 #define pii pair<int,int>
     9 #define pb push_back
    10 const int INF = 0x3f3f3f3f;
    11 const double eps = 1e-6;
    12 const int maxn = 3e3 + 10;
    13 const int maxm = 1e5 + 10;
    14 const ll mod =  998244353;
    15 
    16 int n,m;
    17 vector<int>vec[maxn];
    18 bool used[maxn];
    19 int a[maxn],root,sz[maxn],son[maxn],all;
    20 
    21 void getroot(int u,int fa) {
    22     sz[u] = 1, son[u] = 0;
    23     for(int i = 0; i < vec[u].size(); i++) {
    24         int v = vec[u][i];
    25         if(used[v] || v == fa) continue;
    26         getroot(v,u);
    27         sz[u] += sz[v];
    28         son[u] = max(son[u],sz[v]);
    29     }
    30     son[u] = max(son[u],all - son[u]);
    31     if(son[u] < son[root]) root = u;
    32 }
    33 
    34 bitset<maxm>bit[maxn],ans;
    35 
    36 void calc(int u,int fa) {
    37     sz[u] = 1, bit[u] <<= a[u];
    38     for(int i = 0; i < vec[u].size(); i++) {
    39         int v = vec[u][i];
    40         if(used[v] || v == fa) continue;
    41         bit[v] = bit[u];
    42         calc(v,u);
    43         sz[u] += sz[v];
    44         bit[u] |= bit[v];
    45     }
    46 }
    47 
    48 void solve(int u) {
    49     used[u] = true;
    50     bit[u].reset(), bit[u].set(0);
    51     calc(u,0);
    52     ans |= bit[u];
    53     for(int i = 0; i < vec[u].size(); i++) {
    54         int v = vec[u][i];
    55         if(used[v]) continue;
    56         root = 0;
    57         all = sz[v];
    58         getroot(v,0);
    59         solve(root);
    60     }
    61 }
    62 
    63 int main() {
    64 #ifdef local
    65     freopen("data.txt", "r", stdin);
    66 //    freopen("data.txt", "w", stdout);
    67 #endif
    68     int t;
    69     scanf("%d",&t);
    70     while(t--) {
    71         ans.reset();
    72         scanf("%d%d",&n,&m);
    73         for(int i = 0; i <= n; i++) vec[i].clear(),used[i] = false;
    74         for(int i = 1; i < n; i++) {
    75             int u,v;
    76             scanf("%d%d",&u,&v);
    77             vec[u].push_back(v);
    78             vec[v].push_back(u);
    79         }
    80         for(int i = 1; i <= n; i++) scanf("%d",&a[i]);
    81         root = 0;
    82         son[0] = 1e9;
    83         all = n;
    84         getroot(1,0);
    85         solve(root);
    86         for(int i = 1; i <= m; i++) printf("%d",(int)ans[i]);
    87         printf("
    ");
    88     }
    89     return 0;
    90 }
  • 相关阅读:
    块元素&行内元素
    semantic ui要装什么才能使用
    float属性
    CSS 选择器
    px,em和rem
    CSS各类布局
    一个 / 引起想骂他事件
    使用fastjson 获取json字符串中的数组,再转化为java集合对象
    计算面试题
    Dubbo(二) 一次惨痛的流血事故
  • 原文地址:https://www.cnblogs.com/scaulok/p/9982814.html
Copyright © 2011-2022 走看看