zoukankan      html  css  js  c++  java
  • HDU 6060:RXD and dividing(DFS)

    题目链接

    题意

    给出n个点,要把除1以外的点分成k个集合,然后对于每个集合要和1这个点一起求一个最小生成树,然后问这k个最小生成树的最大总和是多少。

    思路

    因为每个集合都包含1这个点,因此对于每个点都至少有一条到1的路径。可以从1开始DFS,对于每个点u,它和父亲的边的贡献最多可以是min(sz[x], k),因为可以把x的儿子结点分在不同的k个集合里面,这些儿子结点都必须经过x和父亲的边才能到达1。那么对于每条边都这样做一遍。一个DFS可以求出答案。

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 1e6 + 10;
    const int INF = 0x3f3f3f3f;
    const int MOD = 1e9 + 7;
    typedef long long LL;
    struct Edge {
        int v, nxt, w;
    } edge[N*2];
    int n, k, tot, head[N], sz[N];
    LL ans;
    
    void Add(int u, int v, int w) {
        edge[tot] = (Edge) { v, head[u], w }; head[u] = tot++;
        edge[tot] = (Edge) { u, head[v], w }; head[v] = tot++;
    }
    
    void DFS(int u, int fa) {
        sz[u] = 1;
        for(int i = head[u]; ~i; i = edge[i].nxt) {
            int v = edge[i].v, w = edge[i].w;
            if(v == fa) continue;
            DFS(v, u);
            sz[u] += sz[v];
            LL tol = sz[v] < k ? sz[v] : k;
            ans += tol * w;
        }
    }
    
    int main() {
        while(~scanf("%d%d", &n, &k)) {
            memset(head, -1, sizeof(head)); 
            tot = ans = 0;
            for(int i = 1; i < n; i++) {
                int u, v, c; scanf("%d%d%d", &u, &v, &c);
                Add(u, v, c);
            }
            DFS(1, -1);
            printf("%lld
    ", ans);
        } return 0;
    }
    
  • 相关阅读:
    NetworkX-根据权重画图
    Matplotlib 画廊
    NetworkX-画图
    NetworkX-simple graph
    python+networkx
    AttributeError: 'module' object has no attribute 'X509_up_ref'
    python Flask post 数据 输出
    windows环境下批处理实现守护进程
    supervisor自启动
    支持高并发的IIS Web服务器常用设置
  • 原文地址:https://www.cnblogs.com/fightfordream/p/7272521.html
Copyright © 2011-2022 走看看