zoukankan      html  css  js  c++  java
  • [题解] uva 1395 slim span(kruskal最小生成树)

    - 传送门 -

     https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4141

    #1395 - Slim Span

    Time limit: 3.000 seconds

    | Root | Submit Problem Stats
    uDebug Download as PDF |

    (题面见pdf)

     

    - 题意 -

     求一棵最大边与最小边差值最小的生成树.
     

    - 思路 -

     边按权值排序, 然后直接枚举.
     枚举从第 k 大的边开始插入, 然后依次插入比它大的边, 当插入的边生成了树时, 当前边和最开始插入的边的差值就可以用来更新答案了.
     
     细节见代码.
     

    - 代码 -

    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int N = 105;
    const int INF = 1e9;
    
    struct edge {
    	int x, y, v;
    }W[N*N*2];
    
    int F[N];
    int n, m, ans, cnt;
    
    bool cmp (edge a, edge b) { return a.v < b.v; }
    
    int find(int x) { return x == F[x] ? x : F[x] = find(F[x]); }
    
    void add(int t) {
    	int xf = find(W[t].x), yf = find(W[t].y);
    	if (xf == yf) return;
    	F[xf] = yf;
    	cnt ++;
    }
    
    int main() {
    	while ((scanf("%d%d", &n, &m) != EOF) && n) {
    		for (int i = 1; i <= m; ++i)
    			scanf("%d%d%d", &W[i].x, &W[i].y, &W[i].v);
    		sort(W + 1, W + m + 1, cmp);
    		ans = INF;
    		for (int i = 1; i <= m - n + 2; ++i) {
    			for (int j = 1; j <= n; ++j)
    				F[j] = j;
    			cnt = 0;
    			for (int j = i; j <= m; ++j) {
    				add(j);
    				if (cnt == n - 1) {
    					ans = min(ans, W[j].v - W[i].v);
    					break;
    				}
    			}
    		}
    		if (ans == INF) ans = -1;
    		printf("%d
    ", ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    【排序】冒泡排序,C++实现
    【排序】选择排序,C++实现
    【排序】插入排序,C++实现
    【集成学习】 lightgbm原理
    leetcode1310
    leetcode1309
    leetcode1300
    leetcode1302
    leetcode1299
    leetcode1306
  • 原文地址:https://www.cnblogs.com/Anding-16/p/7354020.html
Copyright © 2011-2022 走看看