zoukankan      html  css  js  c++  java
  • 修复公路

    传送门

    题目背景

    A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。

    题目描述

    给出A地区的村庄数N,和公路数M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)

    输入输出格式

    输入格式:

    第1行两个正整数N,M

    下面M行,每行3个正整数x, y, t,告诉你这条公路连着x,y两个村庄,在时间t时能修复完成这条公路。

    输出格式:

    如果全部公路修复完毕仍然存在两个村庄无法通车,则输出-1,否则输出最早什么时候任意两个村庄能够通车。

    输入输出样例

    输入样例#1:
    4 4
    1 2 6
    1 3 4
    1 4 5
    4 2 3
    输出样例#1:
    5

    说明

    N<=1000,M<=100000

    x<=N,y<=N,t<=100000

    题目大意

    修每条公路都有一定时间,请问最早什么时候任意两个村庄都联通

    题解

    并查集

    联通的点放入一个并查集 就是kruskal 都联通就是加入n-1边,每加入一条边少一个集合,最后判断是否剩下一个集合就是判断是否都联通了。

    代码

    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    using namespace std;
    
    int n,m,x,y,sum,gg,cnt,t,k,fa[1005];
    
    struct Edge{
        int x,y,t;
    }edge[200002];
    
    int f(int x){
        return fa[x]==x?x:fa[x]=f(fa[x]);
    }
    
    bool cmp(Edge a,Edge b){
        return a.t<b.t;
    }
    
    int main(){
        scanf("%d%d",&n,&m);gg=n;
        for(int i=1;i<=m;i++){
            scanf("%d%d%d",&x,&y,&t);
            edge[++cnt].x=x;edge[cnt].y=y;edge[cnt].t=t;
            edge[++cnt].x=y;edge[cnt].y=x;edge[cnt].t=t;
        }
        for(int i=1;i<=n;i++)fa[i]=i;
        sort(edge+1,edge+cnt+1,cmp);
        for(k=1;k<=cnt;k++){
            if(sum==n-1)break;
            int fx=f(edge[k].x),fy=f(edge[k].y);
            if(fx!=fy){
                fa[fx]=fy;
                gg--;
                sum++;
            }
        }
        if(gg==1)
        printf("%d
    ",edge[k].t);
        else printf("-1
    ");
        return 0;
    } 
  • 相关阅读:
    BZOJ 1101 莫比乌斯函数+分块
    BZOJ 2045 容斥原理
    BZOJ 4636 (动态开节点)线段树
    BZOJ 2005 容斥原理
    BZOJ 2190 欧拉函数
    BZOJ 2818 欧拉函数
    BZOJ 3123 主席树 启发式合并
    812. Largest Triangle Area
    805. Split Array With Same Average
    794. Valid Tic-Tac-Toe State
  • 原文地址:https://www.cnblogs.com/zzyh/p/7435872.html
Copyright © 2011-2022 走看看