Pagini recente » Cod sursa (job #979217) | Cod sursa (job #2468134) | Cod sursa (job #2984091) | Cod sursa (job #2454860) | Cod sursa (job #2662029)
#include <bits/stdc++.h>
using namespace std;
using ull = unsigned long long;
class InParser {
private:
FILE *fin;
char *buff;
int sp;
char read_ch() {
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, fin);
}
return buff[sp];
}
public:
InParser(const char* nume) {
fin = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
InParser& operator >> (int &n) {
char c;
while (!isdigit(c = read_ch()) && c != '-');
int sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
InParser& operator >> (long long &n) {
char c;
n = 0;
while (!isdigit(c = read_ch()) && c != '-');
long long sgn = 1;
if (c == '-') {
n = 0;
sgn = -1;
} else {
n = c - '0';
}
while (isdigit(c = read_ch())) {
n = 10 * n + c - '0';
}
n *= sgn;
return *this;
}
};
vector<vector<ull>> adj, jda;
vector<ull> vis;
vector<int> stk, comp;
void AddEdge(int a, int b) {
adj[a][b / 64] |= (1ULL << (b % 64));
jda[b][a / 64] |= (1ULL << (a % 64));
}
int Pop(vector<ull>& a, vector<ull>& b) {
for (int i = 0; i < (int)a.size(); ++i) {
ull msk = (a[i] & (~b[i]));
if (msk)
return __builtin_ctzll(msk) + i * 64;
}
return -1;
}
template<int Phase>
void DFS(int node) {
vis[node / 64] |= (1LL << (node % 64));
while (true) {
int vec = Pop((Phase == 0 ? adj : jda)[node], vis);
if (vec == -1) break;
DFS<Phase>(vec);
}
(Phase == 0 ? stk : comp).push_back(node);
}
void Solve(ostream& cout) {
int n = adj.size();
vis.assign(n / 64 + 1, 0);
for (int node = 0; node < n; ++node) {
if (!(vis[node / 64] & (1ULL << (node % 64))))
DFS<0>(node);
}
fill(vis.begin(), vis.end(), 0);
vector<int> ccs_end;
for (int i = n - 1; i >= 0; --i) {
int node = stk[i];
if (!(vis[node / 64] & (1ULL << (node % 64)))) {
DFS<1>(node);
ccs_end.push_back(comp.size());
}
}
cout << ccs_end.size() << '\n';
int b = 0;
for (auto e : ccs_end) {
for (int i = b; i < e; ++i)
cout << comp[i] + 1 << " ";
cout << '\n';
b = e;
}
}
int main() {
InParser cin("ctc.in");
ofstream cout("ctc.out");
int n, m; cin >> n >> m;
adj.assign(n, vector<ull>(n / 64 + 1, 0));
jda = adj;
for (int i = 0; i < m; ++i) {
int a, b; cin >> a >> b; --a; --b;
AddEdge(a, b);
}
Solve(cout);
return 0;
}