Pagini recente » Cod sursa (job #36996) | Cod sursa (job #2551462) | Cod sursa (job #1414105) | Cod sursa (job #3250923) | Cod sursa (job #662210)
Cod sursa(job #662210)
#include <fstream>
#include <iostream>
#include <vector>
#include <stack>
#include <queue>
#include <bitset>
#include <cstdlib>
#define MAXN 100001
using namespace std;
typedef unsigned int uint32;
typedef vector<vector<int> > Graph;
typedef vector<vector<int> > Scc;
bitset<MAXN> visitedNodes_1;
bitset<MAXN> visitedNodes_2;
uint32 uVerticesAdded = 0;
stack<uint32> stNodes;
template<typename T>
class CQueue
{
public:
CQueue(const size_t cap) :
current(0),
capacity(cap),
curSize(0)
{
Q = (T*)malloc((cap+1)*sizeof(T));
}
T front() const
{
return Q[current];
}
void push(const T& elem)
{
const size_t pos = (current+curSize) % capacity;
curSize++;
Q[pos] = elem;
}
void pop()
{
if (curSize != 0)
{
curSize--;
current++;
current %= capacity;
}
}
bool empty() const
{
return (curSize == 0);
}
size_t size()
{
return curSize;
}
void clear()
{
current = 0;
curSize = 0;
}
~CQueue()
{
free(Q);
}
private:
T* Q;
size_t current;
size_t capacity;
size_t curSize;
};
void Kosaraju_1(const Graph& graph, const uint32 node)
{
//if (uVerticesAdded < graph.size())
{
for (uint32 i=0; i<graph[node].size(); ++i)
{
if (false == visitedNodes_1[graph[node][i]])
{
visitedNodes_1[graph[node][i]] = true;
Kosaraju_1(graph, graph[node][i]);
}
}
uVerticesAdded++;
//cout << "Added node = " << node << endl;
stNodes.push(node);
}
}
void Kosaraju_2(const Graph& graph, vector<int>& scc, uint32 node)
{
CQueue<uint32> Q(MAXN);
scc.push_back(node);
visitedNodes_2[node] = true;
Q.push(node);
while (!Q.empty())
{
node = Q.front();
Q.pop();
for (uint32 i=0; i<graph[node].size(); ++i)
{
if (false == visitedNodes_2[graph[node][i]])
{
scc.push_back(graph[node][i]);
visitedNodes_2[graph[node][i]] = true;
Q.push(graph[node][i]);
}
}
}
}
int main()
{
uint32 n, m, numComp=0;
Graph graph, graphT;
Scc sccs;
fstream fin("ctc.in", fstream::in);
fstream fout("ctc.out", fstream::out);
fin >> n >> m;
//cout << n << " " << m << endl;
graph.resize(n);
graphT.resize(n);
sccs.resize(n);
//cout << graph.size() << endl;
for (uint32 i=0; i<m; ++i)
{
uint32 x, y;
fin >> x >> y;
graph[x-1].push_back(y-1);
graphT[y-1].push_back(x-1);
}
for (uint32 i=0; i<n; ++i)
{
if (false == visitedNodes_1[i])
{
visitedNodes_1[i] = true;
Kosaraju_1(graph, i);
}
}
while (!stNodes.empty())
{
const uint32 node = stNodes.top();
stNodes.pop();
//cout << node << endl;
if (false == visitedNodes_2[node])
{
Kosaraju_2(graphT, sccs[numComp], node);
numComp++;
}
}
fout << numComp << "\n";
for (uint32 i=0; i<numComp; ++i)
{
for (uint32 j=0; j<sccs[i].size(); ++j)
{
fout << sccs[i][j]+1 << " ";
}
fout << "\n";
}
fin.close();
fout.close();
return 0;
}