• [Jobdu] 题目1545:奇怪的连通图


    题目描述:

    已知一个无向带权图,求最小整数k。使仅使用权值小于等于k的边,节点1可以与节点n连通。

    输入:

    输入包含多组测试用例,每组测试用例的开头为一个整数n(1 <= n <= 10000),m(1 <= m <= 100000),代表该带权图的顶点个数,和边的个数。
    接下去m行,描述图上边的信息,包括三个整数,a(1 <= a <= n),b(1 <= b <= n),c(1 <= c <= 1000000),表示连接顶点a和顶点b的无向边,其权值为c。 

    输出:

    输出为一个整数k,若找不到一个整数满足条件,则输出-1。 

    样例输入:
    3 3
    1 3 5
    1 2 3
    2 3 2
    3 2
    1 2 3
    2 3 5
    3 1
    1 2 3 
    样例输出:
    3
    5
    -1

    开始看到题目感觉好复杂,先想到的是二分查找,可是即使是二分查找,复杂度也太高了。其实这题就是考并查集,按边的长度排序,第一次发现n与1连通时的边就是所求的k。因为已经排过序了。

     1 #include <iostream>
     2 #include <vector>
     3 #include <algorithm>
     4 #include <cstdio>
     5 using namespace std;
     6  
     7 struct edge_t {
     8     int a, b;
     9     int dist;
    10 };
    11  
    12 int n, m;
    13 vector<edge_t> edges;
    14 vector<int> father;
    15  
    16 int findFather(int x) {
    17     while (x != father[x]) {
    18         x = father[x];
    19     }
    20     return x;
    21 }
    22  
    23 bool cmp(const edge_t &a, const edge_t &b) {
    24     return a.dist < b.dist;
    25 }
    26  
    27 void init() {
    28     for (int i = 0; i < father.size(); ++i) 
    29         father[i] = i;
    30     sort(edges.begin(), edges.end(), cmp);
    31 }
    32  
    33 void solve() {
    34     for (int i = 0; i < m; ++i) {
    35         int fa = findFather(edges[i].a);
    36         int fb = findFather(edges[i].b);
    37         if (fa < fb) father[fb] = fa;
    38         else father[fa] = fb;
    39         if (findFather(n) == 1) {
    40             cout << edges[i].dist << endl;
    41             return;
    42         }
    43     }
    44     cout << "-1" << endl;
    45 }
    46  
    47 int main() {
    48     while (scanf("%d %d", &n, &m) != EOF) {
    49         father.resize(n + 1);
    50         edges.resize(m);
    51         for (int i = 0; i < m; ++i) {
    52             scanf("%d %d %d", &edges[i].a, &edges[i].b, &edges[i].dist);
    53         }
    54         init();
    55         solve();
    56     }
    57     return 0;
    58 }
    59 /**************************************************************
    60     Problem: 1545
    61     User: hupo250
    62     Language: C++
    63     Result: Accepted
    64     Time:640 ms
    65     Memory:2248 kb
    66 ****************************************************************/
  • 相关阅读:
    笔记1
    笔记2
    笔记3
    两个多线程的交替打印
    三个多线程的交替打印
    内部类
    基本反射了解
    键盘监听事件KeyListener
    焦点监听事件FocusListener
    文本框JTextField,密码框JPasswordField
  • 原文地址:https://www.cnblogs.com/easonliu/p/4429249.html
Copyright © 2020-2023  润新知