poj2186

来源:互联网 发布:迪拜的奇葩法律 知乎 编辑:程序博客网 时间:2024/06/02 16:10

Tarjan模板题。建议采用二维vector存储。

学习Tarjan时要注意两个数组:

int DFN[M];                  //深度优先搜索访问次序 int Low[M];                  //能追溯到的最早的次序 

这是学习的网址:http://www.nocow.cn/index.php/Tarjan算法

P.s. Tarjan真心是递归之精髓的体现啊!

下面是标准的Tarjan的模板。

这道题算法其实很清楚,把图的边反向存储,再把图的强连通分量求出来,然后找出入度为零的分量,如果入度为0的强连通分量个数大于1,那么最终解一定是0,否则最终解就是那个入度为零的强连通分量的点的个数。

#include <iostream>#include <string.h>#include <vector>#define MAX_N 10010#define MAX_M 50010using namespace std;vector <int> vec[MAX_N];int dfn[MAX_N], low[MAX_N], stap[MAX_N], belong[MAX_N];int n, m, bcnt, dindex = 0, stop = 0;int rd[MAX_N], rd0cnt;bool instack[MAX_N];int x[MAX_M], y[MAX_M];void tarjan(int v) {int u, l = vec[v].size();dfn[v] = low[v] = ++dindex;instack[v] = true;stap[++stop] = v;for (int i = 0; i < l; i++) {u = vec[v][i];if (!dfn[u]) {tarjan(u);if (low[u] < low[v])low[v] = low[u];}else if (instack[u] && dfn[u] < low[v])low[v] = dfn[u];}if (dfn[v] == low[v]) {bcnt++;do {u = stap[stop--];instack[u] = false;belong[u] = bcnt;}while (u != v);}}int main() {while (cin >> n >> m) {for (int i = 1; i <= m; i++) {cin >> x[i] >> y[i];vec[y[i]].push_back(x[i]);}stop = bcnt = dindex = 0;memset(dfn, 0, sizeof(dfn));for (int i = 1; i <= n; i++)if (!dfn[i]) tarjan(i);memset(rd, 0, sizeof(rd));for (int i = 1; i <= m; i++)if (belong[x[i]] != belong[y[i]])rd[belong[x[i]]]++;int cnt = 0;for (int i = 1; i <= bcnt; i++)if (rd[i] == 0) cnt++;if (cnt > 1) cout << 0 << endl;else {cnt = 0;for (int i = 1; i <= n; i++)if (rd[belong[i]] == 0) cnt++;cout << cnt << endl;}}}


0 0
原创粉丝点击