Cod sursa(job #1473641)

Utilizator stoianmihailStoian Mihail stoianmihail Data 19 august 2015 21:13:20
Problema PScNv Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 2.6 kb
#include <stdio.h>

#define Smerenie 500000
#define Nadejde 250000
#define Dragoste 4096

/**  Algoritm problema "Pscnv", autor Cosmin Silvestru Negruseri:
 *  1) Grupam muchiile dupa cost si determinam maximul dintre costuri "k".
 *  2) Pentru costul "i" de la "1" -> "k" trecem prin listele de adiacenta
 * a costului "i", si trasam muchiile corespunzatoare.
 *  3) Se repeta punctul 2) pana cand find(X) == find(Y).
 *  Multumim Doamne!
**/

typedef struct {
  int u, v, next;
} cell;

int N, M, X, Y, ss;
int pos = Dragoste;     /// pozitia in buff[]
int stack[Nadejde];     /// stiva union-find
int adj[Nadejde + 1];   /// adj[i] este capatul listei de adiacenta pentru costul "i".
cell l[Smerenie + 1];   /// lista muchiilor grupate pe costuri.
int boss[Nadejde + 1];  /// boss[i] este seful nodului "i".
char c, buff[Dragoste]; /// bufferul oferit de sistem.

/** Ia urmatorul caracter din fisier. **/
char getChar(FILE *f) {
  if (pos == Dragoste) {
    fread(buff, 1, Dragoste, f);
    pos = 0;
  }
  return buff[pos++];
}

/** Citeste urmatorul numar. **/
void read(FILE *f, int *result) {
  *result = 0;
  do {
    c = getChar(f);
  } while (!isdigit(c));
  do {
    *result = (*result << 3) + (*result << 1) + c - '0';
    c = getChar(f);
  } while (isdigit(c));
}

/** Incercam sa arate ca si fscanf(). **/
void freef(FILE *f, const char *arg, int *u, int *v, int *w) {
  read(f, &*u), read(f, &*v), read(f, &*w);
}

/** Pune "u" si "v" la capatul listei de adiacenta a lui "w". **/
void addEdge(int u, int v, int w, int p) {
  l[p].u = u, l[p].v = v;
  l[p].next = adj[w];
  adj[w] = p;
}

/** Gaseste radacina nodului "u". **/
int find(int u) {
  for (; boss[u]; u = boss[u]) {
    stack[ss++] = u;
  }
  int root = u;
  while (ss) {
    boss[stack[--ss]] = root;
  }
  return root;
}

/** Reuneste multimea lui "u" cu a lui "v". **/
void unify(int u, int v) {
  int ru = find(u), rv = find(v);
  if (ru != rv) {
    boss[rv] = ru;
  }
}

int main(void) {
  int i, u, v, w, p, k = 1;
  FILE *f = fopen("pscnv.in", "r");

  /// Citeste graful.
  freef(f, "%d %d %d", &N, &M, &X), read(f, &Y);
  for (i = 1; i <= M; i++) {
    freef(f, "%d %d %d", &u, &v, &w);
    addEdge(u, v, w, i);
    if (w > k) {
      k = w;
    }
  }
  fclose(f);

  f = fopen("pscnv.out", "w");

  /// Determina K minim.
  i = 1;
  while ((i <= k) && (find(X) != find(Y))) {
    for (p = adj[i++]; p; p = l[p].next) {
      unify(l[p].u, l[p].v);
    }
  }
  fprintf(f, "%d\n", i - 1);
  fclose(f);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}