Cod sursa(job #3218505)

Utilizator Cezar_RusuCezar Rusu Cezar_Rusu Data 27 martie 2024 12:10:16
Problema Arbore partial de cost minim Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.06 kb
#include <cstdio>

using namespace std;

FILE *input, *output;

#define NMAX 200002
#define MMAX 400002

int T[NMAX], H[NMAX];

void Union(int x, int y);
int Find(int x);

typedef struct {
  int x, y, cost;
} muchie;
muchie M[MMAX];
struct {
  int x, y;
} solutie[MMAX];

void inserare(muchie H[], int &n, muchie x);
void combinare(muchie H[], int n, int i);
muchie extragere(muchie H[], int &n);

int sum;
int n, m;

int main(void) { int i;
	input = fopen("apm.in", "r"), output = fopen("apm.out", "w");

	(void)fscanf(input, "%d %d", &n, &m);
  for (i = 1; i <= m; ++i) {
    (void)fscanf(input, "%d %d %d", &M[i].x, &M[i].y, &M[i].cost);
  }

  for (i = m/2; i >= 1; --i) combinare(M, m, i);

  int rx, ry; muchie a;
  n = 0;
  while (m > 0) {
    a = extragere(M, m);
    rx = Find(a.x);
    ry = Find(a.y);
    if (rx != ry) {
      sum += a.cost;

      ++n;
      solutie[n].x = a.x;
      solutie[n].y = a.y;

      Union(rx, ry);
    }
  }

  (void)fprintf(output, "%d\n", sum);
  (void)fprintf(output, "%d\n", n);
  for (i = 1; i <= n; ++i) (void)fprintf(output, "%d %d\n", solutie[i].x, solutie[i].y);

	fclose(output);
	return 0;
}


muchie extragere(muchie H[], int &n) {
  muchie x = H[1];
  H[1] = H[n]; --n;
  combinare(H, n, 1);
  return x;
}

void combinare(muchie H[], int n, int i) {
  muchie x = H[i];
  int tata = i, fiu = 2 * tata;
  while (fiu <= n) {
    if (fiu+1 <= n && H[fiu].cost > H[fiu+1].cost) ++fiu;
    if (x.cost > H[fiu].cost) {
      H[tata] = H[fiu];
      tata = fiu;
      fiu = 2 * tata;
    } else break;
  }

  H[tata] = x;
}

void inserare(muchie H[], int &n, muchie x) {
  int fiu = n+1, tata = fiu / 2;
  while (tata && H[tata].cost > x.cost) {
    H[fiu] = H[tata];
    fiu = tata;
    tata = fiu / 2;
  }

  H[fiu] = x; ++n;
}


void Union(int x, int y) {
  if (H[x] > H[y]) T[y] = x;
  else if (H[x] < H[y]) T[x] = y;
  else {
    T[y] = x;
    ++H[x];
  }
}

int Find(int x) {
  if (T[x] == 0) return x;
  T[x] = Find(T[x]);
  return T[x];
}