zoukankan      html  css  js  c++  java
  • UVa 1395

    链接:

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

    题意:

    给出一个n(n≤100)结点的图,求苗条度(最大边减最小边的值)尽量小的生成树。

    分析:

    首先把边按权值从小到大排序。对于一个连续的边集区间[L,R],如果这些边使得n个点全部连通,
    则一定存在一个苗条度不超过W[R]-W[L]的生成树(其中W[i]表示排序后第i条边的权值)。
    从小到大枚举L,对于每个L,从小到大枚举R,同时用并查集将新进入[L,R]的边两端的点合并成一个集合,
    与Kruskal算法一样。当所有点连通时停止枚举R,换下一个L(并且把R重置为L)继续枚举。

    代码:

     1 import java.io.*;
     2 import java.util.*;
     3 import static java.lang.Math.*;
     4 import static java.util.Arrays.*;
     5 
     6 public class Main {
     7     Scanner cin = new Scanner(new BufferedInputStream(System.in));
     8     final int INF = 0x3f3f3f3f;
     9     final int UP = 100 + 5;
    10     int n, m, prev[] = new int[UP];
    11     Edge edge[];
    12     
    13     class Edge implements Comparable<Edge> {
    14         int f, b, v;
    15         
    16         @Override
    17         public int compareTo(Edge that) {
    18             return v - that.v;
    19         }
    20     }
    21     
    22     int seek(int v) {
    23         return prev[v] == v ? v : (prev[v] = seek(prev[v]));
    24     }
    25     
    26     int solve() {
    27         int remain, ans = INF;
    28         for(int L = 0; L < m; L++) {
    29             remain = n - 1; // 剩余合并次数
    30             for(int i = 0; i < UP; i++) prev[i] = i; // 初始化并查集
    31             for(int R = L; R < m; R++) {
    32                 int pf = seek(edge[R].f), pb = seek(edge[R].b);
    33                 if(pf == pb) continue;
    34                 prev[pf] = pb;
    35                 if(--remain > 0) continue;
    36                 ans = min(ans, edge[R].v - edge[L].v);
    37                 break;
    38             }
    39         }
    40         return ans == INF ? -1 : ans;
    41     }
    42     
    43     void MAIN() {
    44         while(true) {
    45             n = cin.nextInt();
    46             m = cin.nextInt();
    47             if(n == 0 && m == 0) break;
    48             edge = new Edge[m];
    49             for(int i = 0; i < m; i++) edge[i] = new Edge();
    50             for(int i = 0; i < m; i++) {
    51                 edge[i].f = cin.nextInt();
    52                 edge[i].b = cin.nextInt();
    53                 edge[i].v = cin.nextInt();
    54             }
    55             sort(edge);
    56             System.out.println(solve());
    57         }
    58     }
    59     
    60     public static void main(String args[]) { new Main().MAIN(); }
    61 }
  • 相关阅读:
    用“Keras”11行代码构建CNN
    技术 | 使用深度学习检测DGA(域名生成算法)
    未来的超级智能网络攻击需要AI竞技俱乐部来拯救
    开源中国的代码托管
    Hello Java !
    15-include的使用
    14-递归函数
    13-函数的调用
    12-函数的返回值
    11-函数的参数
  • 原文地址:https://www.cnblogs.com/hkxy125/p/9160445.html
Copyright © 2011-2022 走看看