Cod sursa(job #2763149)

Utilizator Razvan48Capatina Razvan Nicolae Razvan48 Data 12 iulie 2021 00:23:52
Problema Flux maxim de cost minim Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.66 kb
#include <fstream>
#include <vector>

using namespace std;

const int NMAX = 40000;
const int K = 200;

int vecin[1 + NMAX][2];
int vecinK[1 + NMAX][2];

inline int dirLibera(int nod)
{
  if (vecin[nod][0] == 0)
    return 0;
  if (vecin[nod][1] == 0)
    return 1;
  return -1;
}

inline int next(int &nod, int &ant)
{
  if (vecin[nod][0] == ant)
  {
    ant = nod;
    nod = vecin[nod][1];
    return 1;
  }
  else
  {
    ant = nod;
    nod = vecin[nod][0];
    return 0;
  }
}

inline int nextK(int &nod, int &ant)
{
  if (vecinK[nod][0] == ant)
  {
    ant = nod;
    nod = vecinK[nod][1];
    return 1;
  }
  else
  {
    ant = nod;
    nod = vecinK[nod][0];
    return 0;
  }
}

inline int dist(int nod, int dir, int d)
{
  int ant = nod;

  nod = vecinK[nod][dir];
  while (d >= K)
    dir = nextK(nod, ant), d -= K;

  nod = vecin[ant][dir];
  while (d > 0)
    next(nod, ant), d -= 1;

  return ant;
}

inline int capat(int nod, int dir)
{
  int ant = nod;

  nod = vecinK[nod][dir];
  while (nod != 0)
    dir = nextK(nod, ant);

  nod = vecin[ant][dir];
  while (nod != 0)
    next(nod, ant);

  return ant;
}

bool cautaLant(int a, int b, int dirA, int &stAnt, int &st, int &drAnt, int &dr)
{
  if (vecinK[a][1 - dirA] != 0)
  {
    stAnt = vecinK[a][1 - dirA];
    if (vecinK[stAnt][0] == a)
      st = vecin[stAnt][0];
    else
      st = vecin[stAnt][1];
    drAnt = a;
    dr = b;

    return true;
  }
  else
  {
    int lungime = 0;
    stAnt = b;
    st = a;
    while (st != 0)
    {
      lungime++;
      next(st, stAnt);
    }
    swap(st, stAnt);

    drAnt = a;
    dr = b;
    while (dr != 0 && lungime < K)
    {
      lungime++;
      next(dr, drAnt);
    }

    return lungime == K;
  }
}

bool adaugaMuchie(int a, int b)
{
  int dirA = dirLibera(a);
  int dirB = dirLibera(b);

  if (dirA == -1 || dirB == -1) return false;
  if (capat(a, 1 - dirA) == b) return false;

  vecin[a][dirA] = b;
  vecin[b][dirB] = a;

  int st = -1;
  int dr = -1;
  int stAnt = -1;
  int drAnt = -1;

  if (cautaLant(a, b, dirA, stAnt, st, drAnt, dr))
  {
    while (st != b && dr != 0)
    {
      dirA = (vecin[st][0] == stAnt ? 1 : 0);
      dirB = (vecin[dr][0] == drAnt ? 0 : 1);
      vecinK[st][dirA] = dr;
      vecinK[dr][dirB] = st;

      next(st, stAnt);
      next(dr, drAnt);
    }
  }

  return true;
}

bool stergeMuchie(int a, int b)
{
  if (vecin[a][0] != b && vecin[a][1] != b) return false;

  int dirA = (vecin[a][0] == b ? 0 : 1);
  int dirB;

  int st = -1;
  int dr = -1;
  int stAnt = -1;
  int drAnt = -1;

  if (cautaLant(a, b, dirA, stAnt, st, drAnt, dr))
  {
    while (st != b && dr != 0)
    {
      dirA = (vecin[st][0] == stAnt ? 1 : 0);
      dirB = (vecin[dr][0] == drAnt ? 0 : 1);
      vecinK[st][dirA] = 0;
      vecinK[dr][dirB] = 0;

      next(st, stAnt);
      next(dr, drAnt);
    }
  }

  if (vecin[a][0] == b)
    vecin[a][0] = 0;
  else
    vecin[a][1] = 0;

  if (vecin[b][0] == a)
    vecin[b][0] = 0;
  else
    vecin[b][1] = 0;

  return true;
}

pair<int, int> gasesteDist(int nod, int d)
{
  int st = dist(nod, 0, d);
  int dr = dist(nod, 1, d);

  if (st == dr)
    dr = 0;
  if (st > dr)
    swap(st, dr);

  return make_pair(st, dr);
}

pair<int, int> gasesteCapete(int nod)
{
  int st = capat(nod, 0);
  int dr = capat(nod, 1);

  if (st == dr)
    dr = 0;
  if (st > dr)
    swap(st, dr);

  return make_pair(st, dr);
}

int main()
{
  ifstream in("drumuri4.in");
  ofstream out("drumuri4.out");

  int n, m;
  in >> n >> m;

  for (int i = 1; i <= m; i++)
  {
    int tip;
    in >> tip;

    if (tip == 1)
    {
      int a, b;
      in >> a >> b;

      out << (int)adaugaMuchie(a, b) << '\n';
    }
    else if (tip == 2)
    {
      int a, b;
      in >> a >> b;

      out << (int)stergeMuchie(a, b) << '\n';
    }
    else if (tip == 3)
    {
      int a, d;
      in >> a >> d;

      pair<int, int> sol = gasesteDist(a, d);

      int count = (int)(sol.first != 0) + (int)(sol.second != 0);

      out << count << ' ';
      if (sol.first != 0)
        out << sol.first << ' ';
      if (sol.second != 0)
        out << sol.second << ' ';
      out << '\n';
    }
    else
    {
      int a;
      in >> a;

      pair<int, int> sol = gasesteCapete(a);

      int count = (int)(sol.first != 0) + (int)(sol.second != 0);

      out << count << ' ';
      if (sol.first != 0)
        out << sol.first << ' ';
      if (sol.second != 0)
        out << sol.second << ' ';
      out << '\n';
    }
  }

  return 0;
}