zoukankan      html  css  js  c++  java
  • 题解【洛谷P2700】逐个击破

    题面

    [JSOI2008]星球大战 类似的套路,都是运用 反向思维 的好题。

    首先假设所有边都被破坏,然后减去一些不需要被破坏的边的花费就是答案。

    注意我们要求答案最小,就一定要减去边权尽量大的边,因此我们就需要将边权从大到小排序后再处理。

    讲一下具体判断一条边是否不需要被破坏的方式:

    • 设一个数组 (vis_i),表示以 (i) 为代表的连通块中是否存在要被破坏的城市。(fa_i) 表示 (i) 号城市所在的集合的代表,初始 (fa_i=i)其实就是并查集
    • 对于一条边的端点 (u)(v),如果 (vis_{u 的祖先})(vis_{v 的祖先}) 不都为 true,那么这一条边就可以被破坏。还需要进行一些后续的操作。

    代码写起来很简单。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    typedef long long LL;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
        return f * x;
    }
    
    const int INF = 0x3f3f3f3f, N = 100003, M = N << 1;
    
    int n, k;
    int a[N];
    int tot, head[N], ver[M], nxt[M], edge[M];
    int fa[N];
    LL sum;
    bool vis[N];
    struct Node
    {
    	int u, v, w;
    } x[N];
    
    inline void add(int u, int v, int w)
    {
    	ver[++tot] = v, edge[tot] = w, nxt[tot] = head[u], head[u] = tot;
    }
    
    inline bool cmp(Node x, Node y)
    {
    	return x.w > y.w;
    }
    
    int getf(int u)
    {
    	if (fa[u] == u) return u;
    	return fa[u] = getf(fa[u]);
    }
    
    int main()
    {
        n = gi(), k = gi();
        for (int i = 1; i <= k; i+=1) a[i] = gi() + 1, vis[a[i]] = true;
        for (int i = 1; i <= n; i+=1)
        	fa[i] = i;
        for (int i = 1; i < n; i+=1)
        {
        	int u = gi() + 1, v = gi() + 1, w = gi();
        	add(u, v, w), add(v, u, w);
        	x[i] = (Node){u, v, w};
        	sum += w;
        }
        sort(x + 1, x + n, cmp);
        for (int i = 1; i < n; i+=1)
        {
        	int u = getf(x[i].u), v = getf(x[i].v);
        	if (!(vis[u] && vis[v]))
        	{
        		fa[u] = v;
        		vis[v] |= vis[u];
        		sum -= x[i].w;
        	}
        }
        printf("%lld
    ", sum);
        return 0;
    }
    
  • 相关阅读:
    天文漫谈章测试题【第四章】
    天文漫谈章测试题【第三章】
    天文漫谈章测试题【第二章】
    天文漫谈-章测试题【第一章】
    天文漫谈期末考试
    《中国特色社会主义理论与实践》笔记 202001
    教育法学期末考试02MOOC
    教学法学期末考试MOOC01
    教育法学第九章单元测试MOOC
    在Linux平台上如何使用接静态库和共享库
  • 原文地址:https://www.cnblogs.com/xsl19/p/13027578.html
Copyright © 2011-2022 走看看