Cod sursa(job #1282087)

Utilizator catalincraciunCraciun Catalin catalincraciun Data 3 decembrie 2014 22:29:02
Problema A+B Scor 0
Compilator cpp Status done
Runda Arhiva de probleme Marime 5.11 kb
/// Craciun Catalin
///  Infoarena
///   Cezar
///    Centrul grafului
#include <iostream>
#include <fstream>
#include <vector>
#include <ctime>
#include <iomanip>

#define NMax 10005

using namespace std;

ifstream f("cezar.in");
ofstream g("cezar.out");

short n,k;
vector<short> vec[NMax];

class CustomHeap {
public:
      int heapSize;
      int H[NMax]; /// Indexul fiecarui nod din heap
      int P[NMax]; /// Pozitia fiecarui nod in heap
      int V[NMax]; /// Valoarea fiecarui nod, la inceput 1
      int GR[NMax]; /// Gradul fiecarui nod

      CustomHeap() {
            // log ("[HEAP] Allocating a heap");
            heapSize = 0;
      }
      ~CustomHeap() {
            // log ("[HEAP] Deallocating a heap");
            heapSize = 0;
      }

      void eraseFromHeap(int position) {
            // log ("[HEAP] Erasing from heap node " << H[position]);
            if (position > heapSize) return;

            H[position] = H[heapSize];
            P[H[position]] = position;
            heapSize--;
            if (position > 1 && ((GR[H[position/2]] > GR[H[position]]) ||
                  (GR[H[position/2]] == GR[H[position]] && V[H[position/2]] > V[H[position]])))
                  upHeap(position);
            else
                  downHeap(position);
      }
      void insertOnHeap(int node, int value, int grad) {
            // log ("[HEAP] Insert on heap");
            heapSize++;
            H[heapSize] = node;
            P[node] = heapSize;
            V[node] = value;
            GR[node] = grad;
            upHeap(heapSize);
      }
      int minimFromHeap() {
            // log ("[HEAP] Returning minimum from heap");
            return H[1];
      }
      void upHeap(int x) {
            // log ("[HEAP - PRIVATE]: Going up");
            int aux;
            while (x > 1) {
                  if (GR[H[x/2]] > GR[H[x]]) {
                        aux = H[x/2];
                        H[x/2] = H[x];
                        H[x] = aux;

                        P[H[x]] = x;
                        P[H[x/2]] = x/2;

                        x = x/2;
                  } else if (GR[H[x/2]] == GR[H[x]]) {
                        if (V[H[x/2]] > V[H[x]]) {
                              aux = H[x/2];
                              H[x/2] = H[x];
                              H[x] = aux;

                              P[H[x]] = x;
                              P[H[x/2]] = x/2;

                              x = x/2;
                        } else
                              break;
                  } else
                        break;
            }
      }
      void downHeap(int x) {
            // log ("[HEAP - PRIVATE]: Going down");
            while (true) {
                  int minx = x;

                  if (2 * x <= heapSize && ((GR[H[2*x]] < GR[H[minx]]) || (GR[H[2*x]] == GR[H[minx]] && V[H[2*x]] < V[H[minx]])))
                        minx = 2*x;
                  if (2 * x + 1 <= heapSize && ((GR[H[2*x + 1]] < GR[H[minx]]) || (GR[H[2*x + 1]] == GR[H[minx]] && V[H[2*x + 1]] < V[H[minx]])))
                        minx = 2*x + 1;

                  if (minx == x)
                        break;
                  else {
                        int aux = H[x];
                        H[x] = H[minx];
                        H[minx] = aux;

                        P[H[x]] = x;
                        P[H[minx]] = minx;

                        x = minx;
                  }
            }
      }
};
/// ana are mere
CustomHeap *customHeap;

void solve() {

      // log ("Solving input");
      for (int i=1;i<=n;i++) {
            int gradNod = vec[i].size();
            customHeap -> insertOnHeap(i, 1, gradNod);
      }

      while (customHeap -> heapSize > 1) {
            int nodMinim = customHeap -> minimFromHeap();
            customHeap -> eraseFromHeap(customHeap -> P[nodMinim]);
            int valueToAdd = customHeap -> V[nodMinim];
            int vecin = vec[nodMinim][0]; /// Suposing we extract only leaves
            vec[nodMinim].erase(vec[nodMinim].begin());
            /// Searching our extracted node in his parent's neighbour list
            for (unsigned j = 0; j < vec[vecin].size(); j++) {
                  if (vec[vecin][j] == nodMinim) {
                        vec[vecin].erase(vec[vecin].begin() + j);
                        break;
                  }
            }
            int value = customHeap -> V[vecin];
            int nod = vecin;
            int grad = vec[vecin].size();

            int positionToErase = customHeap -> P[vecin];
            /// Updating "father's" value on heap
            customHeap -> V[nod] = value + valueToAdd;
            customHeap -> upHeap (customHeap -> P[nod]);
      }

      g<<customHeap -> minimFromHeap()<<'\n';
}

void read() {

      // log ("Reading input");
      f>>n>>k;
      for (int i=1;i<n;i++) {
            int x, y; f>>x>>y;
            vec[x].push_back(y); vec[y].push_back(x);
      }
}

int main() {

      float oldTime = clock();
      read(); customHeap = new CustomHeap(); solve(); delete customHeap;
      g<<"\n\n"<<"Execution took "<<fixed<<setprecision(7)<<(clock() - oldTime)/CLOCKS_PER_SEC<<'\n';
      f.close(); g.close();
      return 0;
}