|算法讨论|强连通分量Tarjan 学习笔记
2017-03-11 16:56
423 查看
题目
[树形DP, 缩点]BZOJ 2427:缩点后跑树上背包
模板及讲解
参考资料:https://www.byvoid.com/blog/scc-tarjan/
[树形DP, 缩点]BZOJ 2427:缩点后跑树上背包
模板及讲解
参考资料:https://www.byvoid.com/blog/scc-tarjan/
#include<cstdio> #include<cstring> #include<algorithm> #include<stack> #include<vector> #include<cmath> #define ms(i,j) memset(i, j, sizeof(i)); using namespace std; struct node { int x; int y; }; //图里的边 vector<node> q[205]; //边集 stack<int> s; //tarjan栈 int n; int index = 0; //时间戳 int ans = 0; //强连通分量个数即答案 int ex[205]; //是否访问过,0=没访问,-1=在栈中,1=访问完毕 int dn[205], low[205]; //dn为时间戳,low[i]为结点i能追溯到的最早栈中元素 int tarjan(int u) { dn[u]=low[u]=++index; //赋值时间戳和low的初值 ex[u]=-1; //标记在栈中 s.push(u); //放进栈中 node p; for (int i=0;i<q[u].size();i++) { //枚举每一条边(u,v) p = q[u][i]; if (ex[p.y]==0) { //结点没访问过 tarjan(p.y); low[u] = min(low[u], low[p.y]); //树枝,即(u,v)没访问过且u->v } else if (ex[p.y]==-1) //结点在栈中 { low[u] = min(low[u], dn[p.y]); //后向边,即(u,v)中的v在栈中 } } if (dn[u]==low[u]) //找到一个强连通分量 { int e; do { e = s.top(); s.pop(); ex[e] = 1; //标记访问完毕 } while (u!=e); //退栈直到u!=e ans++; } } int main () { scanf("%d", &n); for (int i=1;i<=n;i++) { int a; scanf("%d", &a); while (a!=0) { node r; r.x = i, r.y = a; q[i].push_back(r); scanf("%d", &a); } } ms(ex, 0); ms(dn,0); for (int i=1;i<=n;i++) if (!dn[i]) tarjan(i); printf("%d\n", ans); return 0; }
相关文章推荐
- |算法讨论|平衡树 学习笔记
- |算法讨论|贪心算法 学习笔记
- |算法讨论|二分查找 学习笔记
- |算法讨论|后缀数组 学习笔记
- |算法讨论|线段树1(大白书版本) 学习笔记
- |算法讨论|RMQ 学习笔记
- |算法讨论|树状数组 学习笔记
- |算法讨论|LCA 学习笔记
- |算法讨论|数论数学 学习笔记
- |算法讨论|线段树2 学习笔记
- 算法学习—— tarjan算法求强连通分量 (附带 hdu1827
- |算法讨论|无向图割点和桥 学习笔记
- |算法讨论|Trie树 学习笔记
- |算法讨论|2-SAT 学习笔记
- |算法讨论|状压DP/位运算 学习笔记
- |算法讨论|可并堆 学习笔记
- |算法讨论|树链剖分 学习笔记
- |算法讨论|Hash表 学习笔记
- 【算法学习笔记】81.动态规划 分类讨论 SJTU OJ 1075 括号匹配升级
- |算法讨论|最短路 学习笔记