51nod1640(kruscal)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1640

题意:中文题诶~

思路:kruscal

题目要求是在边权最大值最小的情况下总权值尽量大,注意其中的优先级;

可以先从小到大加边kruscal一遍得到最小的最大边权,再从大到小加边kruscal一遍即可得出答案;

注意第二边kruscal时要先判当前加的边权不大于限制边权再加边,不然构造的并查集是错的;

代码:

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <stdio.h>
 4 #define ll long long
 5 using namespace std;
 6
 7 const int MAXN=2e5+10;
 8 const ll inf=0x7f7f7f7f7f;
 9
10 struct node{
11     int x, y;
12     ll v;
13 }edge[MAXN];
14
15 int pre[MAXN], n, m;
16
17 bool cmp(node a, node b){
18     return a.v < b.v;
19 }
20
21 int find(int x){
22     return pre[x]==x?x:pre[x]=find(pre[x]);
23 }
24
25 ll jion(node edge, ll cnt){
26     if(edge.v>cnt) return 0;
27     int fx=find(edge.x);
28     int fy=find(edge.y);
29     if(fx==fy) return 0;
30     pre[fx]=fy;
31     return edge.v;
32 }
33
34 void init(void){
35     for(int i=1; i<=n; i++){
36         pre[i]=i;
37     }
38 }
39
40 void kruscal(void){
41     ll cnt=0, ans=0, cc=inf;
42     init();
43     sort(edge, edge+m, cmp);
44     for(int i=0; i<m; i++){
45         ll gg=jion(edge[i], cc);
46         cnt=max(cnt, gg);
47     }
48     init();
49     for(int i=m-1; i>=0; i--){
50         ans+=jion(edge[i], cnt);
51     }
52     printf("%lld\n", ans);
53 }
54
55 int main(void){
56     scanf("%d%d", &n, &m);
57     for(int i=0; i<m; i++){
58         scanf("%d%d%lld", &edge[i].x, &edge[i].y, &edge[i].v);
59     }
60     kruscal();
61     return 0;
62 }

时间: 2024-12-24 02:11:46

51nod1640(kruscal)的相关文章

【最小生成树】【kruscal】hdu4786 Fibonacci Tree

假设这张图能够形成具有k条白边的生成树, 则易证k一定形成一个连续的区间[a,b],中间一定不会断开.要是断开--tm怎么可能. 所以求出a,b就好啦,人家都给你把白边赋成1了,直接跑一下最小生成树,再跑一下最大生成树即可咯. #include<cstdio> #include<algorithm> using namespace std; #define N 100010 struct Edge{ int u,v,w; }edges[N]; bool cmp(const Edge

hdu1162(最小生成树 prim or kruscal)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1162 意义:给出一些点,用线问使所有点直接或间接连通,需要多长: 思路:裸最小生成树: 法1: prim算法:MST(Minimum Spanning Tree,最小生成树)问题有两种通用的解法,Prim算法就是其中之一,它是从点的方面考虑构建一颗MST,大致思想是:设图G顶点集合为U,首先任意选择图G中的一点作为起始点a,将该点加入集合V,再从集合U-V中找到另一点b使得点b到V中任意一点的权值最

hihocoder1098最小生成树(kruscal算法)

kruscal算法描述: kruscal算法的思路是:最初,把所有节点都看成孤立的集合,将图中所有的边按权重从小到大排序,然后依次遍历这些边,若边的两个端点在两个不同的集合中,则合并这条边的端点所属的两个集合,直到选出n-1条边将图中的所有n个节点都合并到了同一个集合,n-1次合并就选出了n-1条边,由这n-1条边和图上的n哥节点所构成的就是我们需要的该图的最小生成树. kruscal算法的性能依赖于边的数目,故对于稀疏图的最小生成树问题,采用kruscal算法比较优越. 我的代码: 1 #in

hdu 1102 Constructing Roads Kruscal

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1102 题意:这道题实际上和hdu 1242 Rescue 非常相似,改变了输入方式之后, 本题实际上更适合用Prim来做. 用Kruscal的话要做一些变化. /*Constructing Roads Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s)

【kruscal】【最小生成树】【离线】洛谷 P2266 爱的距离

建图:每个点向它四周的点连边权为两点点权的差的绝对值的边. 由于有多个需要“施法”的点,所以相当于对每个这样的点,询问与它的距离在T以内的最长边的最小值,即多次询问. 最长边最小之类的,肯定是最小生成树没跑了.BUT 若是对每个点这样做的话,肯定会TLE. 所以考虑一次处理出所有询问的答案. 在并查集将两个点集连边的时候,若两个点集的点数和<T,则对这两个集内的询问点都没有影响. 若两个点集的点数和>=T,则若A(B)集原来的点数<T,则A(B)集内的询问点都符合了题意,这个最大值就是当

最小生成树Kruskal——最优布线问题(codevs 1231) (可做Kruscal模板)

题目描述 Description 学校需要将n台计算机连接起来,不同的2台计算机之间的连接费用可能是不同的.为了节省费用,我们考虑采用间接数据传输结束,就是一台计算机可以间接地通过其他计算机实现和另外一台计算机连接. 为了使得任意两台计算机之间都是连通的(不管是直接还是间接的),需要在若干台计算机之间用网线直接连接,现在想使得总的连接费用最省,让你编程计算这个最小的费用. 输入描述 Input Description 输入第一行为两个整数n,m(2<=n<=100000,2<=m<

hihoCoder#1098 最小生成树二&#183;Kruscal算法

原题地址 以前没写过Kruscal算法,写了才知道原来比Prime算法简单多了... 并查集的应用太经典了! 代码: 1 #include <iostream> 2 #include <cstdlib> 3 4 using namespace std; 5 6 #define MAX_EDGE 1000008 7 #define MAX_POINT 100008 8 9 struct Edge { 10 int a; 11 int b; 12 int len; 13 }; 14 1

poj 1258 kruscal

//hnldyhy(303882171) 8:54:04 #include <iostream> // poj 1258#include <algorithm> using namespace std; #define N 105int p[N];void init (int n){ for (int i=1;i<=n;i++) p[i]=i; }int find(int x){ if (p[x]==x)return x; else return p[x]=find(p[x]

BZOJ1821 [JSOI2010]Group 部落划分 Group Kruscal

欢迎访问~原文出处--博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1821 题意概括 平面上有n个点,现在把他们划分成k个部分,求不同部分之间最近距离的最大值. 两个部分的距离就是两个部分中的最近的点对的距离. n<=1000 题解 我们把所有的点全部建边. 然后我们要更新答案,就要尽量弄掉短的边. 于是就按照kruscal那样从短的开始弄. 当然要用并查集. 最后答案就是剩余的有意义的边中最短的一条. 注意最后的处理,我由于这个wa了好多次. 代码 #inclu