Time Limit: 2000MS | Memory Limit: 65536K | |
Total Submissions: 41771 | Accepted: 16955 |
Description
Input
Output
Sample Input
3 3 1 2 2 1 2 3
Sample Output
1
Hint
Source
再Tarjan算法中,有如下定义。
DFN[ i ] : 在DFS中该节点被搜索的次序(时间戳)
LOW[ i ] : 为i或i的子树能够追溯到的最早的栈中节点的次序号
当DFN[ i ]==LOW[ i ]时,为i或i的子树可以构成一个强连通分量。
借这个图说明一下染色
为了打字 以下缩写DFN=LOW为条件
首先DFS 栈里面有1 3 5 6
到第六个节点 已经到达DFS最深处 满足条件 染成棕色 栈里面有1 3 5
返回到5 满足条件 染成橙色 栈里面有1 3
到3
再到4 4可以到1 但是不满足!dfn[v] , 它满足!color[v], low[id] = min(low[id], dfn[v]); low[4] = 1, 不满足条件 栈里面有 1 3 4
回到3 low[id] = min(low[id], low[v]); low[3] = 1, 不满足条件 栈里面有 1 3 4
到1
再到2 2可以到4 但是不满足!dfn[v] , 它满足!color[v], low[id] = min(low[id], dfn[v]); low[2] = 5, 不满足条件 栈里面有 1 3 4 2
再回到1 满足条件 把栈里面的都拿出来染成蓝色 完毕
注意要反向建图(是这样子叫么?)
#include <stdio.h> #include <iostream> #include <vector> #include <algorithm> int N, M; using namespace std; const int si = 10010; vector<int> G[si]; int dfn[si], low[si], color[si], size[si], stk[si]; bool flag[si]; int timelag, colorcnt, stksize; void tarjan(int id) { dfn[id] = low[id] = ++timelag; stk[stksize++] = id; for (int i = 0; i < G[id].size(); i++) { int v = G[id][i]; if (!dfn[v]) {//dfn也是vis的标志 是否来过 tarjan(v); low[id] = min(low[id], low[v]); } else if (!color[v]) { low[id] = min(low[id], dfn[v]); } } if (dfn[id] == low[id]) {//染色 int cnt = 0; colorcnt++; while (stksize) { stksize--; int x = stk[stksize]; color[x] = colorcnt; cnt++; if (x == id) break; } size[colorcnt] = cnt; } } int main() { cin >> N >> M; while (M--) { int a, b; scanf("%d %d", &a, &b); G[b].push_back(a);//反向建图 } for (int i = 1; i <= N; i++) { if (!dfn[i]) tarjan(i);//求强连通分量 dfn也是vis的标志 } for (int i = 1; i <= N; i++) { for (int j = 0; j < G[i].size(); j++) { int x = G[i][j];//i到x的边 但是他们不是同一个颜色的 上图的3和5是这种关系 if (color[i] != color[x]) flag[color[x]] = 1; //x崇拜i 则x所处的强连通分量都崇拜i 所有与x颜色相同的都崇拜i //但是i不崇拜x 否则i和x是同一个强连通分量同一种颜色了 所以扩大到整个x的颜色 } } int num = 0, ans = 0; for (int i = 1; i <= colorcnt; i++) { if (flag[i]) continue; num++; ans = size[i]; } if (num != 1) ans = 0;//只会有一个被其它所有牛崇拜的强连通分量 cout << ans << endl; return 0; }
原文:https://www.cnblogs.com/smatrchen/p/10596563.html