Cod sursa(job #1750792)

Utilizator dementorrDementhor dementorr Data 30 august 2016 23:19:15
Problema Paduri de multimi disjuncte Scor 0
Compilator c Status done
Runda Arhiva educationala Marime 4.92 kb
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>

typedef struct tr_n_t {
  int value;
  struct tr_n_t *left, *right, *parent, *path_parent;
} tree_node_t;

typedef struct {
  tree_node_t *root;
} splay_tree;

void rotate_left (tree_node_t *node) {
  tree_node_t *left = node->left;
  if (left == NULL)
    return;

  tree_node_t *pp = node->path_parent;
  node->path_parent = left->path_parent;
  left->path_parent = pp;
  
  tree_node_t *parent = node->parent;
  left->parent = parent;
  if (parent) {
    if (parent->left == node)
      parent->left = left;
    else if (parent->right == node)
      parent->right = left;
    else
      left->parent = NULL;
  }

  node->parent = left;
  node->left = left->right;
  if (node->left)
    node->left->parent = node;

  left->right = node;
}

void rotate_right (tree_node_t *node) {
  tree_node_t *right = node->right;
  if (right == NULL)
    return;

  tree_node_t *pp = node->path_parent;
  node->path_parent = right->path_parent;
  right->path_parent = pp;

  tree_node_t *parent = node->parent;
  right->parent = parent;
  if (parent) {
    if (parent->left == node)
      parent->left = right;
    else if (parent->right == node)
      parent->right = right;
    else
      right->parent = NULL;
  }

  node->parent = right;
  node->right = right->left;
  if (node->right)
    node->right->parent = node;

  right->left = node;
}

int is_root (tree_node_t *node) {
  return node->parent == NULL;
}

tree_node_t *create_node (int value, tree_node_t *parent, tree_node_t *path_parent) {
  tree_node_t *new = (tree_node_t *) malloc (sizeof (tree_node_t));

  new->value = value;
  new->left = NULL;
  new->right = NULL;
  new->parent = parent;
  new->path_parent = path_parent;

  return new;
}

void splay (tree_node_t *node) {
  tree_node_t *parent, *grandparent;
  
  while (!is_root (node)) {
    parent = node->parent;
    grandparent = parent->parent;

    if (grandparent == NULL) {
      if (parent->left  == node) rotate_left (parent);
      if (parent->right == node) rotate_right (parent);
    } else {
      if (grandparent->left == parent) {
	if (parent->left  == node) { rotate_left  (parent); rotate_left (grandparent); }
	if (parent->right == node) { rotate_right (parent); rotate_left (grandparent); }
      } else {
	if (parent->left  == node) { rotate_left  (parent); rotate_right (grandparent); }
	if (parent->right == node) { rotate_right (parent); rotate_right (grandparent); }
      }
    }
  }
}

void access (tree_node_t *v) {
  tree_node_t *w;
  splay (v);

  if (v->right) {
    v->right->parent = NULL;
    v->right->path_parent = v;
    v->right = NULL;
  }

  while (v->path_parent) {
    w = v->path_parent;
    splay (w);

    if (w->right) {
      w->right->parent = NULL;
      w->right->path_parent = w;
    }
    w->right = v;
    
    v->parent = w;
    v->path_parent = NULL;
    splay (v);
  }
}

tree_node_t *find_root (tree_node_t *v) {
  access (v);

  tree_node_t *crt = v;
  while (crt->left)
    crt = crt->left;

  splay (crt);
  return crt;
}

void link (tree_node_t *v, tree_node_t *w) {
  access (v);
  access (w);
  
  v->left = w;
  w->parent = v;
}

void cut (tree_node_t *v) {
  access (v);

  if (v->left) {
    v->left->parent = NULL;
    v->left = NULL;
  }
}

void inord (tree_node_t *node) {
  if (node) {
    inord (node->left);
    printf ("%c ", node->value);
    inord (node->right);
  }
}

tree_node_t *nodes[100001];

int main(int argc, char *argv[])
{
  /*
  tree_node_t *root1 = create_node ('b', NULL, NULL);
  root1->left = create_node ('a', root1, NULL);
  root1->right = create_node ('e', root1, NULL);

  tree_node_t *root2 = create_node ('l', NULL, root1->left);
  root2->left = create_node ('f', root2, NULL);
  root2->right = create_node ('n', root2, NULL);
  root2->left->left = create_node ('c', root2->left, NULL);
  root2->left->right = create_node ('j', root2->left, NULL);

  tree_node_t *root3 = create_node ('h', NULL, root1->left);
  root3->left = create_node ('d', NULL, NULL);

  tree_node_t *root4 = create_node ('m', NULL, root2->left);
  root4->left = create_node ('k', root4, NULL);
  root4->right = create_node ('p', root4, NULL);

  tree_node_t *root5 = create_node ('g', NULL, root3->left);
  tree_node_t *root6 = create_node ('i', NULL, root3->left);

  rotate_left (root2);
  rotate_right (root2->parent);

  inord (root2);
  
  //access (root4);
  //inord (root4);
  */
  
  
  freopen ("disjoint.in", "r", stdin);
  freopen ("disjoint.out", "w", stdout);
  
  int n, m;
  scanf ("%d %d\n", &n, &m);

  int i;
  for (i = 0; i < n + 1; ++i)
    nodes[i] = create_node(i, NULL, NULL);
  
  for (i = 0; i < m; ++i) {
    int op;
    int v, w;
    
    scanf ("%d %d %d\n", &op, &v, &w);    
    if (op == 2) {
      if (find_root (nodes[v]) == find_root (nodes[w]))
	printf ("DA\n");
      else
	printf ("NU\n");
    } else if (op == 1) {
      link (nodes[v], find_root(nodes[w]));
    } else if (op == 0) {
      cut (nodes[v]);
    }    
  }
  
  return 0;
}