市赛E题---并查集

题意:从1到n有很多道路,但是每条道路有上限, 一张图,判断1到n的道路上的能通过的最小权值的最大值,

思路:并查集(其实就是最大生成树,改掉最小生成树的排序,按照从大到小排序即可)

结构体按从大到小排好序,然后遍历,不同集合合并,如果遍历到这条边,恰好1,n在一个集合里了,就停止,输出该条边的权值。因为向下的边更小了。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<vector>
 5
 6 using namespace std;
 7
 8 const int maxn=1024;
 9 int T, n, m, a, b, l;
10 int p[maxn];
11
12 int Find(int u)
13 {
14     return u==p[u]? u: p[u]=Find(p[u]);
15 }
16
17 struct Edge
18 {
19     int x, y, l;
20     Edge(int x_, int y_, int l_) :x(x_), y(y_), l(l_) {}
21     bool operator <(const Edge& rhs) const
22     {
23         return l<rhs.l;
24     }
25 };
26
27 vector<Edge> v;
28
29 void init()
30 {
31     scanf("%d%d", &n, &m);
32     for(int i =0; i<maxn ; ++i) p[i]=i;
33     v.clear();
34
35     for(int i =0; i<m; ++i)
36     {
37         scanf("%d%d%d", &a, &b, &l);
38         v.push_back(Edge(a, b, l));
39     }
40     sort(v.begin(), v.end());///按权值从大到小排序
41 }
42
43 int solve()
44 {
45     int res=0;
46     for(int i=v.size(); --i>=0;)
47     {
48         Edge& t=v[i];
49         int pu=Find(t.x);
50         int pv=Find(t.y);
51         if(pu!=pv)///如果pu和pv不在一个集合,合并
52         {
53             p[pu]=pv;
54         }
55         if(Find(1) == Find(n))///如果1,n在一个集合就停,向下走的话,权值更小了
56         {
57             res=t.l;
58             break;
59         }
60     }
61     return res;
62 }
63
64 int main()
65 {
66     scanf("%d", &T);
67     while(T--)
68     {
69         init();
70         printf("%d\n", solve());
71     }
72     return 0;
73 }

时间: 2024-08-11 07:35:52

市赛E题---并查集的相关文章

经典算法题每日演练——第十五题 并查集

原文:经典算法题每日演练--第十五题 并查集 这一篇我们看看经典又神奇的并查集,顾名思义就是并起来查,可用于处理一些不相交集合的秒杀. 一:场景 有时候我们会遇到这样的场景,比如:M={1,4,6,8},N={2,4,5,7},我的需求就是判断{1,2}是否属于同一个集合,当然实现方法 有很多,一般情况下,普通青年会做出O(MN)的复杂度,那么有没有更轻量级的复杂度呢?嘿嘿,并查集就是用来解决这个问题的. 二:操作 从名字可以出来,并查集其实只有两种操作,并(Union)和查(Find),并查集

Travel(HDU 5441 2015长春区域赛 带权并查集)

Travel Time Limit: 1500/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2404    Accepted Submission(s): 842 Problem Description Jack likes to travel around the world, but he doesn’t like to wait. Now, he is tr

市赛L题---dfs

题意:一张图,判断5个等级的个数:如果连通块中有m种字母出现,就是m等级(1 <= m <= 5). 思路:dfs连通块类似,注意vis数组放到全局变量里,dfs会返回,因此用到数组的时候需要开全局变量,容易出错. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <string> 5 #define repu(i,a,b) for(int i=a;

2019湘潭校赛 G(并查集)

要点 题目传送 题目本质是每个点必属于两个集合中的一个,伴随的性质是:如果一个人说别人true,则他们一定属于同一阵营:如果说别人fake,一定不属于同一阵营. 每个点拆为\(i\)和\(i + n\)分别代表他属于某种阵营(目前还不确定),然后根据上述性质边读入边合并同类. 这样扫一遍,如果某个\(i\)和\(i + n\)属于同一阵营则矛盾,无解. 若有解,对于每个点扫一遍和他同阵营的人,为了使fakeman尽可能地少,\(<=n\)的人少就把\(<=n\)视为fakeman:否则把\(&

并查集hdu1232

应该是最基本的题 开始还是没有理解透彻 没有理解透彻就不要急着做题 并查集说白了就是把所有的点看看能归成几个集 合 所以首先判断这两点是否在一个集合范围内 如果没在一个集合范围内 就把小的集合赋给大的集合 记住是把小的集合赋给大的集合 把小的集合赋给大的集合 把小的集合赋给大的集合 把小的集合赋给大的集合 3遍 至于为什么 改成大于也对... #include<cstdio> #include<algorithm> using namespace std; int sett[110

acm集训训练赛(二)D题【并查集】

一.题目 Description There is a town with N citizens. It is known that some pairs of people are friends. According to the famous saying that ?The friends of my friends are my friends, too? it follows that if A and B are friends and B and C are friends th

zoj 3659 第37届ACM/ICPC 长春赛区现场赛E题 (并查集)

题意:给出一棵树,找出一个点,求出所有点到这个点的权值和最大,权值为路径上所有边权的最小值. 用神奇的并查集,把路按照权值从大到小排序,然后用类似Kruskal的方法不断的加入边. 对于要加入的一条路,这条路连接这城市x和y,x所在的集合为A, y所在的集合为B, 可以确定A,B集合内的所有路都比当前这条路的权值大.如果让集合B加入集合A,就是让中心城市位于集合A,那么可以确定这两个集合合并之后的总权值为: A的权值总和+B的数量*当前这条路的权值.同样算出让集合B加入集合A的情况,取两者合并后

POJ-2421Constructing Roads,又是最小生成树,和第八届河南省赛的引水工程惊人的相似,并查集与最小生成树的灵活与能用,水过~~~

Constructing Roads Time Limit: 2000MS   Memory Limit: 65536K               Description There are N villages, which are numbered from 1 to N, and you should build some roads such that every two villages can connect to each other. We say two village A

【LeetCode】并查集 union-find(共16题)

链接:https://leetcode.com/tag/union-find/ p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 12.0px Helvetica } [128]Longest Consecutive Sequence  (2018年11月22日,开始解决hard题) 给了一个无序的数组,问这个数组里面的元素(可以重新排序)能组成的最长的连续子序列是多长.本题的时间复杂度要求是 O(N). 本题 array 专题里面有, 链接:https