hdu 3367 Pseudoforest 最大生成树★

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <vector>
 4 #include <algorithm>
 5 using namespace std;
 6
 7 const int maxn = 100005;
 8 int n, m;
 9 struct node
10 {
11     int u, v, c;
12 }g[maxn];
13 long long ans;
14 int fa[maxn];
15 int ff[maxn];
16 int ee[maxn];
17
18 bool cmp(node a, node b){
19     return a.c > b.c;
20 }
21
22 void init(){
23     memset(ff, false, sizeof(ff));
24     memset(ee, false, sizeof(ee));
25     for (int i = 0; i < n; i++){
26         fa[i] = i;
27     }
28 }
29
30 int find(int x){
31     if (x == fa[x])
32         return x;
33     else
34         return fa[x] = find(fa[x]);
35 }
36
37 void Union(int x, int y, int z){
38     int a = find(x);
39     int b = find(y);
40     if (a == b){
41         if (ff[a])
42             return;
43         ans += z;
44         ff[a] = true;
45     }
46     else{
47         if (ff[a] && ff[b])
48             return;
49         ans += z;
50         fa[b] = a;
51         if (ff[a] || ff[b])
52             ff[a] = true;
53     }
54 }
55
56 int main(){
57     while (~scanf("%d%d", &n, &m)){
58         if (n == 0 && m == 0)
59             break;
60         init();
61         int u, v, c;
62         for (int i = 0; i < m; i++){
63             scanf("%d%d%d", &u, &v, &c);
64             g[i].u = u;
65             g[i].v = v;
66             g[i].c = c;
67         }
68         //克鲁斯卡尔
69         sort(g, g + m, cmp);    //按边从小到大排列
70         ans = 0;
71         for (int i = 0; i < m; i++){
72             Union(g[i].u, g[i].v, g[i].c);
73         }
74         printf("%lld\n", ans);
75     }
76     //system("pause");
77     return 0;
78 }
时间: 2024-10-03 20:16:31

hdu 3367 Pseudoforest 最大生成树★的相关文章

HDU 3367 Pseudoforest 最大生成树

题目来源:HDU 3367 Pseudoforest 题意:每个连通块最多可以有一个环 求最大的森林 思路:考虑最大生成树 如果祖先一样没有环 那就合并 如果祖先不一样 如果2棵树都没有环 合并 如果有1棵树有环 合并 标记该棵树有环 #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 100010; struct edge { i

HDU 3367 Pseudoforest(伪森林)(并查集)

题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=3367 题意:在图论中,如果一个森林中有很多连通分量,并且每个连通分量中至多有一个环,那么这个森林就称为伪森林. 现在给出一个森林,求森林包含的最大的伪森林,其大小通过所有边的权值之和来比较. 分析: 1.一开始想的是:在每个连通分量中求一个最大生成树,然后加一条最大的边,再把每个连通分量算出来的值加起来,但WA了.这并不是最优的,因为还存在这种情况:一个连通分量里最初有两个环,但是伪森林要求最多一个

hdu 3367 Pseudoforest (最小生成树)

Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 1526    Accepted Submission(s): 580 Problem Description In graph theory, a pseudoforest is an undirected graph in which every connec

HDU 3367 Pseudoforest

https://vjudge.net/problem/HDU-3367 题意: 一个伪森林是一个每个连通分量至多有一个环的无向图,给出一个图,图中不包含重边和圈,请你求出这个图的权值最大的伪森林. 思路: 一开始想的是用最大生成树,然后加一条最大的不在生成树中的边,wa了,真是可笑题意都没有理解清楚.题中的图可以是非连通的. 之后看了题解,发现是用并查集的思路,先把边从大到小进行排序,之后对于每一条边,我们看它的两个点a,b. 有2大的种情况: 1.a,b在一个连通分量中,并且他们没有被标记,则

hdu 3367 Pseudoforest【伪森林】

Pseudoforest Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 1929    Accepted Submission(s): 745 Problem Description In graph theory, a pseudoforest is an undirected graph in which every conne

hdu 3367 Pseudoforest(并查集)

题意:求图的一最大联通子图,其中最多包含一个环. 思路:利用求最小生成树的方法(kruskal),排序时从大到小排序.连接时有三种情况: 1.一边有环,一边没有(可能两点已经在同一集合,也可能不在) 2.两边都没有环 3.两边都有环 如图: 1 #include<iostream> 2 #include<cstdio> 3 #include<cstdlib> 4 #include<cstring> 5 #include<string> 6 #in

【HDOJ】3367 Pseudoforest

并查集. 1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 #define MAXN 10005 6 #define INF 0xffffff 7 8 typedef struct { 9 int c, s, e; 10 } edge_st; 11 12 edge_st edges[100005]; 13 int pre[MAXN]; 14 int deg[MAXN]; 15 int n,

hdu 2686 Matrix &amp;&amp; hdu 3367 Matrix Again (最大费用最大流)

Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1394    Accepted Submission(s): 758 Problem Description Yifenfei very like play a number game in the n*n Matrix. A positive integer number

HDU 3367 Hotel

参照这个博客的做法:请戳 ,还有这个的讲解: 询问区间中满足条件的连续最长区间通常属于区间合并问题. 节点增加4个域,lx:从区间左边数连续空房间的数目.rx:从区间右边数连续空房间的数目.ax:该区间中连续空房间的总数目 col:记录该区间住人的状态,1表示全住满,0表示全空,-1表示有可以住的房间. 查询是否有连续空房间数目num的时候,先查询左边,当tree[v].lx >= num的时候递归左区间:再查询中间,当tree[v*2].lx +tree[v*2+1].rx >= num直接