HDU-4313 Matrix 最小生成树,集合划分
2012-07-27 02:37
417 查看
该题就是考的是如何花最小的代价使得一棵树划分开且不含后同类节点。
我们将边按从大到小的顺序排好序,然后就是看是否这条边能够使得两个同类的节点连在一起,如果能够的话,那么这条边就是我们要选择的划分边。首先将特征值保留起来,并通过并查集扩充给标记点。
代码如下:
我们将边按从大到小的顺序排好序,然后就是看是否这条边能够使得两个同类的节点连在一起,如果能够的话,那么这条边就是我们要选择的划分边。首先将特征值保留起来,并通过并查集扩充给标记点。
代码如下:
#include <cstring> #include <cstdlib> #include <cstdio> #include <map> #include <algorithm> using namespace std; int N, M, set[100005], have[100005]; struct Edge { int x, y, fee; bool operator < (Edge t) const { return fee > t.fee; } }e[100005]; int find(int x) { return set[x] = x == set[x] ? x : find(set[x]); } void merge(int a, int b) { set[a] = b; if (have[a]) { have[b] = 1; } } int main() { int T, a, b, c; long long int sum; scanf("%d", &T); while (T--) { sum = 0; memset(have, 0, sizeof (have)); map<int,int>mp; scanf("%d %d", &N, &M); set[N-1] = N-1; for (int i = 0; i < N-1; ++i) { scanf("%d %d %d", &e[i].x, &e[i].y, &e[i].fee); set[i] = i; } for (int i = 0; i < M; ++i) { scanf("%d", &c); have[c] = 1; } sort(e, e + N - 1); for (int i = 0; i < N-1; ++i) { int a = find(e[i].x), b = find(e[i].y); if (have[a] && have[b]) { sum += e[i].fee; continue; } merge(a, b); } printf("%I64d\n", sum); } return 0; }
相关文章推荐
- HDU 4313 Matrix(并查集|最小生成树变种)
- hdu 4313 - Matrix(最小生成树,并查集)
- HDU 4313 Matrix (最小生成树)
- hdu 4313 Matrix (最小生成树krusual)
- !HDU 4313 破坏导弹攻城计划-连通图-(最小生成树变形)
- HDU 4313 最小生成树
- HDU 4408 Minimum Spanning Tree (图的最小生成树计数 Kruskal + Matrix_Tree定理)
- 最小生成树MST的Kruskal算法+并查集(链表实现)划分连通分量和集合,并查集可以保存多个集合
- HDU4313-2012多校二-最小生成树,集合划分
- hdu 还是畅通工程 (基础)(最小生成树)(Prim算法 && Kruskal算法)
- hdu - 4313 - Matrix - 树形dp 或者 贪心
- hdu 畅通工程再续(最小生成树)(Prim算法 && Kruskal算法)
- HDU 1863 畅通工程(最小生成树 kruskal算法)
- HDU 3371 Connect the Cities 最小生成树
- HDU 1301 Jungle Roads(最小生成树Kruskal)
- (step6.1.3)hdu 1875(畅通工程再续——最小生成树)
- hdu 1879 继续畅通工程 (并查集+最小生成树)
- 【BZOJ1016】【JSOI2008】最小生成树计数 & 【BZOJ1543】生成树计数 (kruskal+matrix_tree定理)
- hdu 1875畅通工程再续-prim最小生成树
- HDU 1875 畅通工程再续 (最小生成树 水)