Cod sursa(job #1466637)

Utilizator stoianmihailStoian Mihail stoianmihail Data 29 iulie 2015 18:31:21
Problema PScNv Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.26 kb
#include <queue>
#include <cstdio>
#include <cctype>
#include <climits>

#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))
#define Smerenie 500001
#define Nadejde 250001
#define Dragoste 65536
#define MAX_K 1001

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

typedef struct {
  int v, k;
} cerr;

int N;
int M;
int X;
int Y;
char c;
int d[Nadejde];
int adj[Nadejde];
cell l[Smerenie];
cerr list[Nadejde];
int pos = Dragoste;
char seen[Nadejde];
char buff[Dragoste];
std::queue <int> Q[MAX_K + 1];

/** Returneaza urmatorul caracter din "f". **/
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));
}

/** Inlocuim fscanf()-ul. **/
void freef(FILE *f, const char *arg, int *u, int *v, int *k) {
  read(f, &*u), read(f, &*v), read(f, &*k);
}

/** Adauga-l pe "v" la lista de adiacenta a lui "u". **/
void addEdge(int u, int v, int k, int p) {
  l[p].v = v;
  l[p].k = k;
  l[p].next = adj[u];
  adj[u] = p;
}

/** Sorteaza crescator vectorul "list". **/
void qSort(int begin, int end) {
  int e = end, b = begin, pivot = list[(e + b) >> 1].v;
  while (b <= e) {
    while (list[b].v < pivot) {
      b++;
    }
    while (list[e].v > pivot) {
      e--;
    }
    if (b <= e) {
      cerr tmp = list[b];
      list[b++] = list[e];
      list[e--] = tmp;
    }
  }
  if (begin < e) {
    qSort(begin, e);
  }
  if (b < end) {
    qSort(b, end);
  }
}

/** Sorteaza lista de adiacenta a nodului "u". **/
void getAdj(int u) {
  int size = 0;
  for (pos = adj[u]; pos; pos = l[pos].next) {
    list[size].v = l[pos].v;
    list[size++].k = l[pos].k;
  }
  if (size > 0) {
    qSort(0, size - 1);
    size = 0;
    for (pos = adj[u]; pos; pos = l[pos].next) {
      l[pos].v = list[size].v;
      l[pos].k = list[size++].k;
    }
  }
}

/** Determina "k" minim pana la Y. **/
int bellFord(int u, int max) {
  int i, v, curr;
  d[u] = 0;
  Q[0].push(u);
  for (i = 0; i <= max; i++) {
    while (!Q[i].empty()) {
      u = Q[i].front();
      Q[i].pop();
      if (!seen[u]) {
        seen[u] = 1;
        /** Pentru fiecare vecin. **/
        for (pos = adj[u]; pos; pos = l[pos].next) {
          v = l[pos].v;
          curr = MAX(l[pos].k, d[u]);
          /** Daca am gasit un "k" mai bun. **/
          if (curr < d[v]) {
            d[v] = curr;
            Q[curr].push(v);
          }
        }
      }
    }
  }
  return d[Y];
}

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

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

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

  /** Sorteaza listele de adiacenta. **/
  for (u = 1; u <= N; u++) {
    getAdj(u);
    d[u] = INT_MAX;
  }
  fprintf(f, "%d\n", bellFord(X, max));
  fclose(f);

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