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);
        }
    } 
  • 相关阅读:
    window 窗口对象http://www.diybl.com/course/1_web/javascript/jsjs/2007104/76401.html
    Web开发中的Drag&Drop完全手册http://www.cnblogs.com/birdshome/archive/2006/07/22/457369.aspx
    [转载]window 的 setTimeout() 與 clearTimeout() 方法
    javascript this详解(转) http://www.cnblogs.com/felix2007/archive/2007/03/21/682670.html
    关闭浏览器弹出对话框事件onbeforeunload http://www.blogjava.net/jennyli/articles/82351.html
    页面跳转http://www.9ba.cn/post/235.html
    POJ 3667 Hotel
    hdu 2511 汉诺塔 X
    UESTC Another LCIS
    Hdu 1576 A/B
  • 原文地址:https://www.cnblogs.com/GetcharZp/p/8974663.html
Copyright © 2011-2022 走看看