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

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】

    A地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车。政府派人修复这些公路。
    给出A地区的村庄数N,和公路数M,公路是双向的。并告诉你每条公路的连着哪两个村庄,并告诉你什么时候能修完这条公路。问最早什么
    时候任意两个村庄能够通车,即最早什么时候任意两条村庄都存在至少一条修复完成的道路(可以由多条公路连成一条道路)


    【输入格式】

    第1行两个正整数N,M(N<=1000,M<=100000) 下面M行,每行3个正整数x, y, t,告诉你这条公路连着x,y两个村庄,在时间t时能修复完成这条公路。(x<=N,y<=N,t<=100000)

    【输出格式】

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

    【数据规模】

    Sample Input1

    4 4
    1 2 6
    1 3 4
    1 4 5
    4 2 3
    
    
    
    

    Sample Output1

    5

    【题解】

    这是一道最小生成树问题<->所有的点都互相连通;
    然后和最小生成树不同。我们在给边以边权从小到大排序之后。不是直接递增n-1个边权,而是遇到一个边
    权就与当前遇到的最大边权比较。如果比其大就更新最大边权。然后我们要输出的也是最大边权。
    克鲁斯卡尔算法要排序边。。。不要顺手写成排序点的个数了。。不然9个WA等着你。。因为恰好样例
    如果你把边写成点了。。。可以过。。。。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <iostream>
    
    using namespace std;
    
    struct bian //用结构体来存边。原因是写sort的比较函数时比较方便。
    {
    	int x, y, z;
    };
    
    int n, m, f[1001]; //f是并查集的数组。
    bian a[100001];
    
    void input_data()
    {
    	scanf("%d%d", &n, &m); //输入点和边的个数。
    	for (int i = 1; i <= m; i++)
    		scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].z);
    }
    
    int cmp(const bian &a, const bian &b) //这是比较函数 用于sort
    {
    	if (a.z < b.z) //按边权从小到大排序即可。会连同结构体中的x和y一起排序。
    		return 1;
    	return 0;
    }
    
    int findfather(int x) //找根节点函数。
    {
    	if (f[x] != x)
    		f[x] = findfather(f[x]); //顺便进行路径压缩。
    	return f[x];
    }
    
    void get_ans()
    {
    	for (int i = 1; i <= n; i++) //给并查集数组初始化。
    		f[i] = i;
    	bool flag = false;
    	int num = 0, now = 0;
    	for (int i = 1; i <= m; i++) //枚举m条边
    	{
    		int r1 = findfather(a[i].x), r2 = findfather(a[i].y); //找到两个点所属的集合。
    		if (r1 != r2) //如果不是在同一个集合中。
    		{
    			num++; //递增边数
    			f[r1] = r2; //把这两个集合合并在一起。
    			if (a[i].z > now) //如果能更新当前找到的最大边权则更新。
    				now = a[i].z;
    			if (num == n - 1) //如果找齐n-1条边了。则表示可以全部连同了。
    			{
    				flag = true;
    				break; //结束枚举
    			}
    		}
    	}
    	if (!flag)
    		printf("-1");
    	else //最后输出找到的最大边权即可。
    		printf("%d
    ", now);
    }
    
    int main()
    {
    	input_data();
    	sort(a + 1, a + 1 + m, cmp); //从1..m进行排序。
    	get_ans();
    	return 0;
    }


  • 相关阅读:
    mysql/mariadb基于ssl的主从复制
    原创工具binlog2sql:从MySQL binlog得到你要的SQL
    [转]MySQL DBA面试全揭秘
    mysql my.cnf 配置建议
    mysql配置文件 /etc/my.cnf 详细解释
    [转]expect实现ssh自动交互
    Linux中的lo回环接口详细介绍
    Docker最全教程——从理论到实战(五)
    Docker最全教程——从理论到实战(四)
    Docker最全教程——从理论到实战(一)
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7632324.html
Copyright © 2011-2022 走看看