Pagini recente » Cod sursa (job #1024944) | Cod sursa (job #3312951) | Cod sursa (job #2019862) | Cod sursa (job #424822) | Cod sursa (job #3355799)
// why do i keep trying to do oop although i know it makes me 10x slower and the code at the end is even worse......
#include <fstream>
#include <vector>
#include <algorithm>
#warning In this world, its either mukbang or be mukbanged
using namespace std;
ifstream cin("ctc.in");
ofstream cout("ctc.out");
struct CondensedGraphNode {
vector<int> nodes;
vector<CondensedGraphNode*> nxt;
};
int curExitTime = 0; vector<bool> vis;
void dfs(vector<vector<int>>& originalNxt, int node, vector<int>& storeExitTimeHere)
{
curExitTime++;
if (vis[node])
return;
vis[node] = true;
for (auto nn : originalNxt[node])
{
dfs(originalNxt, nn, storeExitTimeHere);
}
storeExitTimeHere[node] = curExitTime;
}
vector<int> exitTime;
bool cmp(int a, int b) {
return exitTime[a] > exitTime[b];
}
void dfs2(vector<vector<int>> nxt, int pos, vector<CondensedGraphNode*>& whereIs, CondensedGraphNode* addr)
{
if (whereIs[pos] != nullptr)
return;
whereIs[pos] = addr;
addr->nodes.push_back(pos);
for (auto it:nxt[pos])
{
dfs2(nxt, it, whereIs, addr);
}
}
vector<CondensedGraphNode*> korasaju(vector<vector<int>> originalNxt) {
// make prv
vector<vector<int>> originalPrv;
for (unsigned i = 0; i < originalNxt.size(); i++)
originalPrv.push_back({});
for (unsigned i = 0; i < originalNxt.size(); i++)
{
for (auto j : originalNxt[i])
{
originalPrv[j].push_back(i);
}
}
// get exit time
exitTime.resize(originalNxt.size());
curExitTime = 0;
vis.clear();
vis.resize(originalNxt.size());
for (unsigned i = 0; i < originalNxt.size(); i++)
{
if (!vis[i])
dfs(originalNxt, i, exitTime);
}
// sort by it
vector<int> ordering;
for (unsigned i = 0; i < originalNxt.size(); i++)
ordering.push_back(i);
sort(ordering.begin(), ordering.end(), cmp);
fill(vis.begin(), vis.end(), false);
vector<CondensedGraphNode*> ret;
vector<CondensedGraphNode*> whereIs(originalNxt.size());
for (auto pos : ordering)
{
if (whereIs[pos] == nullptr)
{
ret.push_back(new CondensedGraphNode());
dfs2(originalPrv, pos, whereIs, ret.back());
}
}
for (unsigned curNode = 0; curNode < originalNxt.size(); curNode++)
{
for (auto otherNode : originalNxt[curNode])
{
if (whereIs[curNode] != whereIs[otherNode])
whereIs[curNode]->nxt.push_back(whereIs[otherNode]);
}
}
return ret;
}
int n, m;
vector<vector<int>> nxt;
int main()
{
cin >> n >> m;
nxt.resize(n);
for (int i = 0; i < m; i++)
{
int u, v;
cin >> u >> v;
u--; v--;
nxt[u].push_back(v);
}
vector<CondensedGraphNode*> condensed = korasaju(nxt);
/* Debug
for (int i = 0; i < condensed.size(); i++) {
printf("%i:\n init: ", i);
for (auto it:condensed[i]->nodes)
printf("%i ", it);
printf("\n nxt size %i\n", condensed[i]->nxt.size());
}
// */
cout << condensed.size() << "\n";
for (auto it:condensed)
{
for (auto it2:it->nodes)
{
cout << it2+1 << " ";
}
cout << "\n";
}
return 0;
}