您的位置:首页 > 其它

HDU 1269 迷宫城堡 最大强连通图题解

2017-05-13 12:43 411 查看
寻找一个迷宫是否是仅仅有一个最大强连通图。

使用Tarjan算法去求解,经典算法。必需要学习好,要自己创造出来是十分困难的了。

參考资料:https://www.byvoid.com/blog/scc-tarjan/

const int N = 10001;

vector<int> gra
;
stack<int> stk;
bool inStack
;
int dfsNum
;
int backTrackNum
;
int cur, sum;
int n, m;

void Tarjan(int u)
{
inStack[u] = true;
dfsNum[u] = backTrackNum[u] = ++cur;
stk.push(u);

for (int i = 0; i < (int)gra[u].size(); i++)
{
int v = gra[u][i];
if (!dfsNum[v]) Tarjan(v), backTrackNum[u] = backTrackNum[v] < backTrackNum[u]? backTrackNum[v] : backTrackNum[u];
else if (inStack[v]) backTrackNum[u] = backTrackNum[v] < backTrackNum[u]?

backTrackNum[v] : backTrackNum[u];
}
if (backTrackNum[u] == dfsNum[u])
{
++sum;
while (stk.size())
{
int v = stk.top(); stk.pop();
inStack[v] = false;
if (u == v) break;
}
}
}

void solveTarjan()
{
sum = cur = 0;
memset(dfsNum, 0, sizeof(dfsNum));
for (int i = 1; i <= n; i++)
{
if (!dfsNum[i]) Tarjan(i);
}
}

void initGraph()
{
int a, b;
for (int i = 1; i <= n; i++) gra[i].clear();//别忘了清空
for (int i = 0; i < m; i++)
{
scanf("%d %d", &a, &b);
gra[a].push_back(b);
}
}

int main()
{
while (scanf("%d %d", &n, &m) && n)
{
initGraph();
solveTarjan();
if (sum == 1) puts("Yes");
else puts("No");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: