题目传送门

题意:如何花最小的代价使得一棵树划分开且不含同类节点

分析:当一条边连接的左右集合同类点小于等于1,那么不用删除,将两个集合合并,要求最小代价,那么贪心思想将权值降序排序,删除后剩下的就是最小值了。树形DP的方法以后再补上

收获:进一步理解Kruskal的算法过程,碰到新的问题要往经典的算法模型上转换

代码:

/************************************************
* Author        :Running_Time
* Created Time  :2015-8-24 10:48:20
* File Name     :D.cpp************************************************/#include <cstdio>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cmath>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <bitset>
#include <cstdlib>
#include <ctime>
using namespace std;#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
typedef long long ll;
const int N = 1e5 + 10;
const int INF = 0x3f3f3f3f;
const int MOD = 1e9 + 7;
struct UF   {int rt[N], rk[N];void init(void)   {memset (rt, -1, sizeof (rt));memset (rk, 0, sizeof (rk));}int Find(int x)  {return rt[x] == -1 ? x : rt[x] = Find (rt[x]);}void Union(int x, int y) {x = Find (x), y = Find (y);if (x == y) return ;if (rk[x] >= rk[y]) {rt[y] = x;    rk[x] += rk[y];}else  {rt[x] = y;    rk[y] += rk[x];}}bool same(int x, int y)  {return (Find (x) == Find (y));}
}uf;
struct Edge {int u, v, w;bool operator < (const Edge &r) const {return w > r.w;}
};
int n, k;
vector<Edge> G;int main(void)    {int T;  scanf ("%d", &T);while (T--)  {scanf ("%d%d", &n, &k);uf.init ();   G.clear ();ll ans = 0;for (int u, v, w, i=1; i<n; ++i)   {scanf ("%d%d%d", &u, &v, &w);    ans += w;G.push_back ((Edge) {u, v, w});}sort (G.begin (), G.end ());for (int x, i=0; i<k; ++i) {scanf ("%d", &x);    uf.rk[x] = 1;}for (int i=0; i<n-1; ++i)  {int u = G[i].u, v = G[i].v, w = G[i].w;u = uf.Find (u); v = uf.Find (v);if (uf.rk[u] + uf.rk[v] <= 1)    {ans -= w; uf.Union (u, v);}}printf ("%I64d\n", ans);}return 0;
}

  

转载于:https://www.cnblogs.com/Running-Time/p/4755054.html

Kruskal HDOJ 4313 Matrix相关推荐

  1. Kruskal HDOJ 1233 还是畅通工程

    题目传送门 1 /* 2 最小生成树之kruskal算法--并查集(数据结构)实现 3 建立一个结构体,记录两点和它们的距离,依照距离升序排序 4 不连通就累加距离,即为最小生成树的长度 5 */ 6 ...

  2. hdoj 3376,2686 Matrix Again 【最小费用最大流】

    题目:hdoj 3376 Matrix Again 题意:给出一个m*n的矩阵,然后从左上角到右下角走两次,每次仅仅能向右或者向下,出了末尾点其它仅仅能走一次,不能交叉,每次走到一个格子拿走这个格子中 ...

  3. 【转】并查集MST题集

    转自:http://blog.csdn.net/shahdza/article/details/7779230 [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 ...

  4. ACM比赛经验、刷题记录及模板库总结(更新中)

    前言 本文所提及的部分题目代码,可以在我的Github上找到 第一部分 经验分享及感受 第二部分 刷题记录 一.基础算法&程序语言 //strlen()函数的复杂度是O(n)要小心 //截取字 ...

  5. HDOJ 1863畅通工程(最小生成树kruskal算法并查集实现)

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1863 最小生成树kruskal算法:http://www.zhuoda.org/irini/78592.h ...

  6. HDOJ水题集合1:最小生成树(Kruskal)

    1001 畅通工程 HDOJ1232 并查集集合个数 畅通工程 Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/32768 K ( ...

  7. Kruskal算法 - C语言详解

    最小生成树 在含有n个顶点的连通图中选择n-1条边,构成一棵极小连通子图,并使该连通子图中n-1条边上权值之和达到最小,则称其为连通网的最小生成树.  例如,对于如上图G4所示的连通网可以有多棵权值总 ...

  8. Kruskal算法的C语言程序

    Kruskal算法是有关图的最小生成树的算法.Kruskal算法是两个经典的最小生成树算法之一,另外一个是Prim算法. 程序来源:Kruskal's Algorithm. 百度百科:Kruskal算 ...

  9. ACM模板--邻接矩阵 无向图 Prim Kruskal Dijkstra

    /*** C++: Dijkstra算法获取最短路径(邻接矩阵)** @author skywang* @date 2014/04/24*/#include <iomanip> #incl ...

最新文章

  1. 『Numpy』常用方法记录
  2. 看看HashSet源码
  3. 3.1 哈尔空间 V0
  4. Oracle编程入门经典 第2章 SQLPlus和基本查询
  5. GeneralUpdate实现应用程序更新
  6. NS2仿真分析无线网络的攻击防御(1)
  7. Maven——windows下安装配置及IDEA设置本地仓库的步骤总结
  8. 计算机系统-电路设计07-上升沿D触发器的内部电路实现/移位寄存器/串行接口/并行接口
  9. 算法导论18.1-4
  10. Linux虚拟网络基础 — Tap
  11. OceanBase基本概念
  12. 初中晨读必看古诗名句
  13. 使用httpModule做权限系统
  14. 韵达快递单号可以批量查询吗
  15. 单片机外部晶振-XTAL和EXTAL引脚
  16. 用java实现邮件发送
  17. HTML——使用 img 标签插入 avi 文件
  18. C++里消除Wunused
  19. 马斯克再次在推特闯祸 年产50万辆电动汽车推文涉嫌违反和解协议
  20. 常见排序算法(C语言实现)

热门文章

  1. Hibernate如何一个类映射两个表
  2. 什么是集群(cluster)
  3. 金融业(互联网金融)创新---我的实地考察和见解
  4. 18、正则表达式中常用字符
  5. Linux下的XAMPP基本配置技巧(设置虚拟主机、添加FTP账户等)
  6. sqlite3 外键支持
  7. 一、Nginx常见问题
  8. 前端vue显示柱状图_Vue接入Echarts 显示柱状图饼图
  9. flask返回json数据到前端_小白学Flask第六天| abort函数、自定义错误方法、视图函数的返回值...
  10. 外部工具连接SaaS模式云数据仓库MaxCompute实战:商业BI分析工具篇