Cod sursa(job #541427)

Utilizator vlad_DVlad Dumitriu vlad_D Data 25 februarie 2011 11:01:10
Problema Lazy Scor 100
Compilator cpp Status done
Runda Romanian Master in Mathematics and Sciences 2011, Ziua 1 Marime 1.91 kb
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>

using namespace std;

typedef long long LL;

struct nod 
{
  int a, b, p;
  LL c1, c2;
  nod(){};
  nod(int _a, int _b, LL _c1, LL _c2, int _p)
  {
    a = _a; b = _b; c1 = _c1; c2 = _c2;
    p = _p;
  }
};
bool operator <(const nod &a, const nod &b)
{
  if (a.c1 < b.c1) return true;
  if (a.c1 > b.c1) return false;
  //c1 * c2 < c1 * c2
  int z1 = 0, z2 = 0;
  int p1 = 1, p2 = 1;
  if (a.c1 == 0 || a.c2 == 0) z1 = 1;
  if (b.c1 == 0 || b.c2 == 0) z2 = 1;
  if (a.c1 < 0) p1 ^= 1;
  if (a.c2 < 0) p1 ^=1;
  if (b.c1 < 0) p2 ^= 1;
  if (b.c2 < 0) p2 ^=1;
  if (z1 && z2) return false;
  if (z1 && p2) return false;
  if (z1 && !p2) return true;
  if (z2 && p1) return true;
  if (z2 && !p1) return false;
  
  if (p1 && p2) {
    if (log(a.c1) + log(a.c2) > log(b.c1) + log(b.c2)) return true;
    return false;
  }
  if (!p1 && !p2) {
    if (log(abs(a.c1)) + log(abs(a.c2)) < log(abs(b.c1)) + log(abs(b.c2)))
      return true;
    return false;
  }
  if (p1 && !p2) return true;
  return false;
}

int n, m;
nod v[200100];
int vset[200100];
int rank[200100];
inline int create_set(int x)
{
  vset[x] = x;
  rank[x] = 0;
}

int find_set(int x)
{
  if (x != vset[x]) vset[x] = find_set(vset[x]);
  return vset[x];
}
void join(int x, int y)
{
  x = find_set(x);
  y = find_set(y);
  if (rank[x] > rank[y]) vset[y] = x;
  else vset[x] = y;
  if (rank[x] == rank[y]) rank[y]++;
}
int main()
{
  freopen("lazy.in", "r", stdin); 
  freopen("lazy.out", "w", stdout);
  scanf("%d %d", &n, &m);
  for (int i = 0; i < m; ++i)
  {
    int a, b; LL c1, c2;
    scanf("%d %d %lld %lld", &a, &b, &c1, &c2);
    v[i] = nod(a, b, c1, c2, i + 1);
  }
  sort(v, v + m);
  for (int i = 1; i <= n; ++i) create_set(i);
  for (int i = 0; i < m; ++i)
  {
    int x = find_set(v[i].a);
    int y = find_set(v[i].b);
    if (x == y) continue;
    printf("%d\n", v[i].p);
    join(x, y);
  }
  return 0;
}