hdu 3367 最大伪森林(kruskal)

最大伪森林:原图的一个子图,在子图的各个连通分量中至多有一个环,且各边权和最大。

方法:kruskal,只是排序按边权从大到小,合并的时候注意判断是否构成多个环。

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdio>
 5 using namespace std;
 6
 7 const int N = 10000;
 8 const int M = 100000;
 9 int f[N];
10 bool cycle[N];
11
12 struct Edge
13 {
14     int u, v, w;
15     bool operator < ( const Edge & o ) const
16     {
17         return w > o.w;
18     }
19 } edge[M];
20
21 int findf( int x )
22 {
23     if ( f[x] != x ) f[x] = findf(f[x]);
24     return f[x];
25 }
26
27 int main ()
28 {
29     int n, m;
30     while ( scanf("%d%d", &n, &m) != EOF )
31     {
32         if ( n == 0 && m == 0 ) break;
33         for ( int i = 0; i < m; i++ )
34         {
35             scanf("%d%d%d", &edge[i].u, &edge[i].v, &edge[i].w);
36         }
37         for ( int i = 0; i < n; i++ )
38         {
39             f[i] = i;
40         }
41         sort( edge, edge + m );
42         memset( cycle, 0, sizeof(cycle) );
43         int sum = 0;
44         for ( int i = 0; i < m; i++ )
45         {
46             int u = edge[i].u, v = edge[i].v, w = edge[i].w;
47             u = findf(u), v = findf(v);
48             if ( u == v )
49             {
50                 if ( !cycle[u] )
51                 {
52                     sum += w;
53                     cycle[u] = 1;
54                 }
55             }
56             else
57             {
58                 if ( cycle[u] && cycle[v] )
59                 {
60                     continue;
61                 }
62                 sum += w;
63                 f[u] = v;
64                 if ( cycle[u] || cycle[v] )
65                 {
66                     cycle[v] = 1;
67                 }
68             }
69         }
70         printf("%d\n", sum);
71     }
72     return 0;
73 }
时间: 2024-10-17 00:20:37

hdu 3367 最大伪森林(kruskal)的相关文章

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): 1929    Accepted Submission(s): 745 Problem Description In graph theory, a pseudoforest is an undirected graph in which every conne

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

【hdu3367】Pseudoforest(伪森林)

http://acm.hdu.edu.cn/showproblem.php?pid=3367 题目大意 伪森林就是一个无向图,这个无向图有多个连通块且每个连通块只有一个简单环. 给你一个无向图,让你找这个图的一个最大生成伪森林(即边权之和最大). 题解 考虑到用Kruscal算法搞最大生成树时,每次加入一条边之前都必须保证边的这两点在之前属于两个连通块,就是为了防止出现环. 即如果加入的边的两点在一个没有环的连通块里的话,就会出现一个环. 那么我们把Kruscal算法改造一下,如果这条边的两点在

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

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

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

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

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直接