• NYOJ 925 国王的烦恼 (并查集)


    题目链接

    描述

    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之间的桥不能使用,居民们会抗议。
      对于样例:第一天后2和3之间的桥不能使用,不影响。第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。第三天后3和4之间的桥不能使用,居民们会抗议。
      对于样例:第一天后2和3之间的桥不能使用,不影响。第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。第三天后3和4之间的桥不能使用,居民们会抗议。
      对于样例:第一天后2和3之间的桥不能使用,不影响。第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。第三天后3和4之间的桥不能使用,居民们会抗议。
      对于样例:第一天后2和3之间的桥不能使用,不影响。第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。第三天后3和4之间的桥不能使用,居民们会抗议。

    分析:

    其实这题是最大生成树的问题,因为每过一天各小岛之间的桥的寿命全部减少一天,应该按桥的寿命从大到小来排序,每次把桥两端的小岛连接起来,若发现这个小岛已经被联通了,就不用再记录此时两个小岛之间桥的寿命了,因为两个小岛之间已经有寿命更长的桥连接了(直接或者间接)。到最后直接统计有多少寿命不同的桥(如果寿命相同,就意味着同一天有多次抗议,然而居民只能一天抗议一次)。

    代码:

    #include<stdio.h>
    #include<string.h>
    #include<iostream>
    #include<algorithm>
    #include<stack>
    #include<math.h>
    using namespace std;
    int parent[10009];
    struct Node
    {
        int x;///a号小岛
        int y;///b号小岛
        int t;///能用的时间
    } node[100009];
    
    bool cmp(Node a,Node b)
    {
        return a.t>b.t;///按照能用的时间从大到小排序
    }
    
    int Find(int num)///找num的父亲
    {
        if(num==parent[num])
            return num;
        else
            return parent[num]=Find(parent[num]);
    }
    int main()
    {
        int n,m;
        int Time[100009];
        int flag=0;
        while(~scanf("%d%d",&n,&m))
        {
            flag=0;
            for(int i=0; i<=n; i++)
                parent[i]=i;
            for(int i=0; i<m; i++)
            {
                scanf("%d%d%d",&node[i].x,&node[i].y,&node[i].t);
            }
            sort(node,node+m,cmp);
            int pa,pb;
            for(int i=0; i<m; i++)
            {
                pa=Find(node[i].x);
                pb=Find(node[i].y);
                if(pa!=pb)///代表node[i].x与node[i].y是不连通的,也就意味着没有办法通行了
                {
                    parent[pa]=pb;///让他俩成为连通的
                    Time[flag++]=node[i].t;///在把他们之间能够通行的时间存下
                }
            }
            // cout<<"flag==="<<flag<<endl;
            // cout<<"去重函数"<<endl;
            // unique(Time,Time+flag);
            int sum=unique(Time,Time+flag)-Time;///去重函数,因为可能在同一天内多个地方都不能够通行了,但是这算是一次
            printf("%d
    ",sum);
        }
        return 0;
    }
  • 相关阅读:
    使用 ServiceStack 构建跨平台 Web 服务
    .NET的微型Web框架 Nancy
    orcale复制表结构及其数据
    利用PL/SQL Developer工具导出数据到excel,导入excel数据到表
    PLSQL导入/导出数据方法
    基于Quqrtz.NET 做的任务调度管理工具
    Web监听器导图详解(转)
    GIT分支管理是一门艺术(转)
    我需要完全理解这部分代码才能确保它能够正常工作,如果由我来修复代码中的问题,我是不会这么写的,因此希望你也不要这么来写(转)
    不要学习代码,要学会思考(转)
  • 原文地址:https://www.cnblogs.com/cmmdc/p/6741911.html
Copyright © 2020-2023  润新知