好久没写了,最近发懒,加上大部分时间都在做学校的voj,倒是很少想起来这儿发帖了。昨天刚考完oj,10道题只A了3道,但也算比去年有进步吧。。感觉我回头还应该自学些高级数据结构,否则根本应付不过来。
今天发现学校oj论坛上有一道poj 2186的题,一看大概是要求强连通分量来把图缩成树处理,然而网上大部分解法都是Tarjan或者Torasaju。。。我就查了下算法导论,第二十二章倒也提到过一种做法,就是先dfs,然后按回溯时间由后到前在其补图上再跑一遍dfs,这一遍能够保证没有横向边,从而能够做到将其正确输出。学校oj也是坑人,poj上已经过了,然而这边一直WA,后来把while scanf那一句去掉一下就过了,无法理解了。。。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define MAXN 10010
#define MAXE 50010
typedef int Edge;
typedef pair Ele;
typedef long long ll;
int outDegree[MAXN];
Ele finishTime[MAXN];
int order[MAXN];
class binGraph
{//graph with ante graph
public:
binGraph(int nn, int mm) :n(nn), m(mm)
{
for (int i = 0; i < n; i++)
edges[0][i].clear();
for (int i = 0; i < n; i++)
edges[1][i].clear();
for (int i = 0; i < m; i++) {
int u, v;
scanf("%d %d", &u, &v);
_addEdge(u - 1, v - 1, 1);
}
memset(_componentSize, 0, sizeof(_componentSize));
memset(finishTime, 0, sizeof(finishTime));
}
void dfs(int No,Ele finishArray[],int order[])
{
memset(visited, 0, sizeof(visited));
_finishTime = 0;
int componentName = 0;
for (int i = 0; i < n; i++) {
int u = order == NULL ? i : order[i];
if (!visited[u]) {
int compoSize=_dfs(No, u, finishArray, componentName);
_componentSize[componentName++] = compoSize;
}
}
_sccNumber = componentName;
}
void rebuild()
{//before graphs discarded
memset(outDegree, 0, sizeof(outDegree));
for (int i = 0; i < n; i++) {
int u = _componentName[i];
for (int j = 0; j < edges[0][i].size(); j++) {
int v = _componentName[edges[0][i][j]];
if ((u!=v)) {
outDegree[u]++;
}
}
}
n = _sccNumber;
int ans = 0;
int count = 0;
for (int i = 0; i < n; i++) {
if (outDegree[i] == 0) {
count++;
ans = _componentSize[i];
}
}
printf("%d\n", count == 1 ? ans : 0);
}
private:
int n, m;
vector edges[2][MAXN];
bool visited[MAXN];
int _finishTime;
int _sccNumber;
int _componentName[MAXN];
int _componentSize[MAXN];
void _addEdge(int u, int v, int w)
{//w ignored here
edges[0][u].push_back(v);
edges[1][v].push_back(u);//ante graph
}
int _dfs(int No, int s, Ele finishArray[], int sccNumber)
{
int ret = 0;
stack dfsStack;
while (dfsStack.empty() == false)
dfsStack.pop();
dfsStack.push(s);
while (!dfsStack.empty()) {
int u = dfsStack.top();
visited[u] = true;
bool visitAll = true;
for (int i = 0; i < edges[No][u].size(); i++) {
int v = edges[No][u][i];
if (!visited[v]) {
visitAll = false;
visited[v] = true;
dfsStack.push(v);
}
}
if (visitAll) {
finishArray[u].first = _finishTime++;
_componentName[u] = sccNumber;
dfsStack.pop();
ret++;
}
}
return ret;
}
};
bool comp(Ele e1, Ele e2)
{
return e1.first > e2.first;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
binGraph bg(n, m);
for (int i = 0; i < n; i++)
finishTime[i].second = i;
bg.dfs(0, finishTime, NULL);
sort(finishTime, finishTime + n, comp);
for (int i = 0; i < n; i++)
order[i] = finishTime[i].second;
bg.dfs(1, finishTime, order);//sort anteGraph bon defiAjo
bg.rebuild();
return 0;
}
现在poj累计38道题了。。。路漫漫其修远兮啊