Cod sursa(job #2115478)

Utilizator TincaMateiTinca Matei TincaMatei Data 26 ianuarie 2018 19:59:45
Problema Componente tare conexe Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.03 kb
#include <bits/stdc++.h>

using namespace std;

const int MAX_N = 100000;
const int MAX_M = 200000;
vector<int> graph[1+MAX_N];
vector<pair<int, int> > g2[1+MAX_N];
long long cost[1+MAX_N];
int a[MAX_M], b[MAX_M], c[MAX_M];
int stiva[1+MAX_N], top;
int id[1+MAX_N], low[1+MAX_N], lastid;
bool instack[1+MAX_N];
int comp[1+MAX_N], lastcomp;
long long smen[20001], dp[1+MAX_N];

vector<vector<int> > ctcuri;

void ctc(int nod) {
  id[nod] = low[nod] = ++lastid;
  stiva[top++] = nod;
  instack[nod] = true;
  for(auto it: graph[nod])
    if(id[it] == 0) {
      ctc(it);
    } else if(instack[nod])
      low[nod] = min(low[nod], low[it]);
  if(id[nod] == low[nod]) {
    lastcomp++;
    dp[lastcomp] = -1;
    vector<int> ctcu;
    do {
      comp[stiva[top - 1]] = lastcomp;
      instack[stiva[top - 1]] = false;
      --top;
      ctcu.push_back(stiva[top]);
    } while(stiva[top] != nod);
    ctcuri.push_back(ctcu);
  }
}

long long getdp(int nod) {
  if(dp[nod] == -1) {
    dp[nod] = cost[nod];
    for(auto it:g2[nod])
      if(getdp(it.first) + it.second + cost[nod] > dp[nod])
        dp[nod] = getdp(it.first) + it.second + cost[nod];
  }
  return dp[nod];
}

int main() {
  int n, m, x, s;
  freopen("ctc.in", "r", stdin);
  freopen("ctc.out", "w", stdout);
  scanf("%d%d", &n, &m);
  for(int i = 0; i < m; ++i) {
    scanf("%d%d", &a[i], &b[i]);
    graph[a[i]].push_back(b[i]);
  }
  for(int i = 1; i <= 20000; ++i)
    smen[i] = (long long)-i * (i + 1) / 2 + smen[i - 1];
  for(int i = 1; i <= n; ++i)
    if(id[i] == 0)
      ctc(i);

  for(int i = 0; i < m; ++i) {
    if(comp[a[i]] == comp[b[i]]) {
      int p;
      p = sqrt(2 * c[i]);
      if((p + 1) * (p + 2) == 2 * c[i])
        ++p;
      cost[comp[a[i]]] += (long long)c[i] * (p + 1) + smen[p];
    } else
      g2[comp[a[i]]].push_back(make_pair(comp[b[i]], c[i]));
  }
  printf("%d\n", ctcuri.size());
  for(int i = 0; i < ctcuri.size(); ++i) {
    for(int j = 0; j < ctcuri[i].size(); ++j)
      printf("%d ", ctcuri[i][j]);
    printf("\n");
  }
  //printf("%lld", getdp(comp[s]));
  return 0;
}