[HAOI2006]旅行COMF

根据数据范围求解,有,好了,直接暴力贪心地选择一段值连续的边,然后判断是否联通即可。

所以我们只要预先对边按照排个序,然后用并查集判断是否联通即可。

#include <bits/stdc++.h>

using namespace std;

const int N = 5e3 + 10;

struct Edge {
  int x, y, w;

  Edge(int _x = 0, int _y = 0, int _w = 0) : x(_x), y(_y), w(_w) {}

  void read() {
    scanf("%d %d %d", &x, &y, &w);
  }

  bool operator < (const Edge &t) const {
    return w > t.w;
  }
}a[N];

int n, m, s, t, fa[N];

void init() {
  for (int i = 1; i <= n; i++) {
    fa[i] = i;
  }
}

int find(int rt) {
  return rt == fa[rt] ? rt : fa[rt] = find(fa[rt]);
}

int main() {
  // freopen("in.txt", "r", stdin);
  // freopen("out.txt", "w", stdout);
  // ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  scanf("%d %d", &n, &m);
  for (int i = 1; i <= m; i++) {
    a[i].read();
  }
  scanf("%d %d", &s, &t);
  sort(a + 1, a + 1 + m);
  const int inf = 0x3f3f3f3f;
  int ans_max = inf, ans_min = 1;
  for (int i = 1; i <= m; i++) {
    int cur_max = a[i].w, cur_min = inf, flag = 0;
    init();
    for (int j = i; j <= m; j++) {
      int fx = find(a[j].x), fy = find(a[j].y);
      if (fx != fy) {
        fa[fx] = fy;
      }
      if (find(s) == find(t)) {
        cur_min = a[j].w;
        flag = 1;
        break;
      }
    }
    if (flag) {
      if ((double)cur_max / cur_min < (double)ans_max / ans_min) {
        ans_max = cur_max;
        ans_min = cur_min;
      }
    }
  }
  if (ans_max == inf) {
    puts("IMPOSSIBLE");
  }
  else {
    int d = __gcd(ans_max, ans_min);
    if (d == ans_min) {
      printf("%d\n", ans_max / d);
    }
    else {
      printf("%d/%d\n", ans_max / d, ans_min / d);
    }
  }
  return 0;
}