zoukankan      html  css  js  c++  java
  • G

    - 题目大意

        给出N个点,M条边,求出一棵包含N个点的树,且树的最大权值-最小权值达到最小。

    - 解题思路

        我们可以先把边排序,枚举最小的,然后利用kruskal加边,当图第一次连通的时候当前的边就是尽可能小的最大边,更新答案即可。

    - 代码

    #include<algorithm>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    const int MAX = 1e6;
    const int INF = 0x3f3f3f;
    int fa[MAX];
    int sum,sum1,tmp;
    void init(int n)
    {
    	for (int i = 1; i <= n; i++)
    	{
    		fa[i] = i;
    	}
    }
    
    struct Edge {
    	int u, v, w;
    	bool operator<(const Edge &rhs)const {
    		return w < rhs.w;
    	}
    }e[MAX];
    
    int find(int x)
    {
    	if (x == fa[x])
    		return x;
    	else
    		return fa[x] = find(fa[x]);
    }
    
    bool Union(int x, int y)
    {
    	int fx = find(x), fy = find(y);
    	if (fx == fy)
    		return false;
    	fa[fx] = fy;
    	return true;
    }
    
    void kruskal(int n,int m)
    {
    	sort(e, e + m);
    	for (int j = 0; j < m; j++)
    	{
    		init(n);
    		sum = 0;
    		int minn = INF, maxn = -INF;
    		for (int i = j; i < m; i++)
    		{
    			int u = e[i].u, v = e[i].v, w = e[i].w;
    			if (Union(u, v))
    			{
    				sum ++;
    				maxn = max(maxn, w);
    				minn = min(minn, w);
    
    			if (sum == n - 1)
    			{
    				tmp = min(tmp, (maxn - minn));
    				break;
    			}
    			}
    		}
    	}
    }
    
    int main()
    {
    	int n, m;
    	while (scanf("%d%d", &n, &m))
    	{
    		if (n == 0 && m == 0)
    			break;
            tmp=INF;
    		for (int i = 0; i<m; i++)
    		{
    			scanf("%d%d%d", &e[i].u, &e[i].v, &e[i].w);
    		}
    		kruskal(n,m);
    		if (tmp==INF)
    			printf("-1
    ");
    		else
    			printf("%d
    ", tmp);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    编写可维护的JavaScript代码(部分)
    Canvas
    初识ES6
    vue.js入门上
    ASP.NET中的物理路径与虚拟路径
    慎用标签选择器
    PHP服务器负载判断
    mac下安装redis
    mac安装memcache
    MySQL定时检查是否宕机并邮件通知
  • 原文地址:https://www.cnblogs.com/alpacadh/p/8449447.html
Copyright © 2011-2022 走看看