zoukankan      html  css  js  c++  java
  • [蓝桥杯][历届试题]国王的烦恼------并查集

    时间限制: 1Sec 内存限制: 128MB 提交: 93 解决: 23

    题目描述
      C国由n个小岛组成,为了方便小岛之间联络,C国在小岛间建立了m座大桥,每座大桥连接两座小岛。两个小岛间可能存在多座桥连接。然而,由于海水冲刷,有一些大桥面临着不能使用的危险。 

    如果两个小岛间的所有大桥都不能使用,则这两座小岛就不能直接到达了。然而,只要这两座小岛的居民能通过其他的桥或者其他的小岛互相到达,他们就会安然无事。但是,如果前一天两个小岛之间还有方法可以到达,后一天却不能到达了,居民们就会一起抗议。 

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

    下文中的样例说明 
    第一天后2和3之间的桥不能使用,不影响。 
    第二天后1和2之间,以及1和3之间的桥不能使用,居民们会抗议。 
    第三天后3和4之间的桥不能使用,居民们会抗议。 
    数据规模和约定 
    对于100%的数据,1< =n< =10000,1< =m< =100000,1< =a,  b< =n,  1< =t< =100000。 

    输入
    输入的第一行包含两个整数n,  m,分别表示小岛的个数和桥的数量。 
    接下来m行,每行三个整数a,  b,  t,分别表示该座桥连接a号和b号两个小岛,能使用t天。小岛的编号从1开始递增。
    输出
    输出一个整数,表示居民们会抗议的天数。
    样例输入
    4  4 
    1  2  2 
    1  3  2 
    2  3  1 
    3  4  3 
    样例输出
    2
    <ahref="http://www.dotcpp.com/oj/problem1435.html">http://www.dotcpp.com/oj/problem1435.html</a>
    
    1.使用并查集
    2.使用一个结构体数组保存输入的桥梁的数据
    3.根据每个桥梁断开的天数进行排序,从大到小进行排序,反向思考。从最后一个断掉的桥梁开始修桥,如果修的桥连通了两个不同的分支,并且和上一个连通两个不同分支的桥梁对应的天数不是同一天,那么天数加一。
    4.使用一个变量last_day记录上一个连通两个不同的分支的桥梁断裂的天数。
    5.然后就是并查集的操作。
    
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define maxn 100010 
    using namespace std;
    int m,n,parent[maxn],days;
    typedef struct Qiao{
        int start,end,day;
    }Qiao;
    Qiao Bridge[maxn];
    int cmp(Qiao x,Qiao y){  return x.day>y.day; }
    int find(int son)
    {
        if(parent[son]==son) return son;
        else return parent[son]=find(parent[son]);
    }
    int unite(int x,int y)//返回值记录是否是同一个连通的分支 
    {
        int boss1=find(x);
        int boss2=find(y);
        if(boss1!=boss2)
        {
            parent[boss1]=parent[boss2];
            return 0; 
        }
        return 1;
    }
    int main(void)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++) parent[i]=i; 
        for(int i=1;i<=m;i++) 
            scanf("%d%d%d",&(Bridge[i].start),&(Bridge[i].end),&(Bridge[i].day)); 
        sort(Bridge+1,Bridge+m+1,cmp);
        int last_day=-1;
        for(int i=1;i<=m;i++)
        {
            /*
            int boss1=find(Bridge[i].start);
            int boss2=find(Bridge[i].end);
            if(boss1 != boss2)
            {
                unite();   
            } 
            */
            int able=unite(Bridge[i].start,Bridge[i].end);
            if(Bridge[i].day != last_day && able==0) days++,last_day=Bridge[i].day;
        }
        printf("%d",days);
        return 0;
    }
  • 相关阅读:
    [转]拜占庭故障 & Paxos 算法
    如何让 YARN 支持 CNPM 的完整加速
    面试必问系列:悲观锁和乐观锁的那些事儿
    ajax下载文件的坑
    mac 装homebrew
    SLF4J报错问解决
    java追加文件
    CentOS 清理空间
    Dockerfile 通过 ARG 设置 ENV 无效的原因
    GoLang 中发送 email 邮件
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8733130.html
Copyright © 2011-2022 走看看