zoukankan      html  css  js  c++  java
  • nyoj 925 国王的烦恼 (并查集)

    国王的烦恼

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:2
     
    描述

        C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起发起抗议。

        现在C国的国王已经知道了每座桥能使用的天数,超过这个天数就不能使用了。现在他想知道居民们一共会发起多少次抗议。

     
    输入
      多组测试数据。
      每组数据先输入两个正整数n和m。
      接下来m行,每行三个整数a, b, t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。(1≤n≤10000,1≤m≤100000,1<=a,b<=n,1≤t≤100000)
    输出
      输出一个整数,表示居民们发起抗议的次数。
    样例输入
    4 4
    1 2 2
    1 3 2
    2 3 1
    3 4 3
    样例输出
    2
    提示
    对于样例:
    第一天后2和3之间的桥不能使用,不影响。
    第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。
    第三天后3和4之间的桥不能使用,居民们会抗议。
    /**
        分析:该题是,判断第i天的非连通区域和第i+1天的非连通区域
                若第i+1天的非连通区域比第i天的非连通区域多 说明:桥断了、居民抗议、cnt ++
                
                所以我们可以逆向思维 <断桥  <==>  修桥>(将数据按照天数由大到小排列):
                    若将两个桥 my_join 的时候桥没有连通 cnt ++  <同时要考虑是否和上一个数据是同一天(因为居民每天最大抗议一次)> 
        数据结构:并查集
        模板:
            pre [100005];
            void init () {
                for (int i = 1; i <= n; ++ i) {
                    pre [i] = i;
                }
                return ;
            } 
            
            int my_find (int x) {
                int n = x;
                while (n != pre [n]) {
                    n = pre [n];
                }
                int i = x, j;
                while (n != pre [i]) {
                    j = pre [i];
                    pre [i] = n;
                    i = j;
                }
            }
            
            bool my_join (int a, int b) {
                int n1 = my_find (a), n2 = my_find (b);
                if (n1 != n2) {
                    pre [n1] = n2;
                    return true;
                } else {
                    return false;
                }
            }
    **/ 

    C/C++代码实现:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <stack>
    #include <queue>
    #include <map>
    
    using namespace std;
    
    int n, m, pre [10005];
    
    struct node {
        int x, y, w;
    }P [100005];
    
    void init () {
        for (int i = 1; i <= n; ++ i) {
            pre [i] = i;
        }
        return ;
    }
    
    bool cmp (node a, node b) {
        return a.w > b.w;
    }
    
    int my_find (int x) {
        int n = x;
        while (n != pre [n]) {
            n = pre [n];
        }
        int i = x, j;
        while (n != pre [i]) {
            j = pre [i];
            pre [i] = n;
            i = j;
        }
        return n;
    }
    
    bool my_join (int a, int b) {
        int n1 = my_find (a), n2 = my_find (b);
        if (n1 != n2) {
            pre [n1] = n2;
            return true;
        }
        return false;
    }
    
    int main () {
        while (~scanf ("%d%d", &n, &m)) {
            init();
            int cnt = 0, my_first = -1;
            for (int i = 0; i < m; ++ i) {
                scanf ("%d%d%d", &P[i].x, &P[i].y, &P[i].w);
            }
            sort (P, P + m, cmp);
            for (int i = 0; i < m; ++ i) {
                if (my_join (P[i].x, P[i].y) && my_first != P[i].w) {
                    ++ cnt;
                    my_first = P[i].w; // 每一天最多抗议1次 
                }
            }
            printf ("%d
    ", cnt);
        }
    } 
  • 相关阅读:
    某个牛人做WINDOWS系统文件详解
    常用ASP脚本程序集锦
    LINUX基础:文件安全与权限
    proftpd+mysql+quota
    apache2.0.49tomcat5.0.19jk2建立virtualHost
    URL Redirection(转) Anny
    顶级域名后缀列表(转) Anny
    \u4E00\u9FA5意义 Anny
    How to POST Form Data Using Ruby(转) Anny
    How to get rid of 'Enter password to unlock your login keyring' in Ubuntu(转) Anny
  • 原文地址:https://www.cnblogs.com/GetcharZp/p/8974663.html
Copyright © 2011-2022 走看看