蒟蒻复习之-----Tarjan
来源:互联网 发布:李谷一 知乎 编辑:程序博客网 时间:2024/06/05 14:06
蒟蒻复习之—–Tarjan
//强连通图的判断方法
//作为复习篇不讲原理
[noip2015]信息传递
//就是找一个最小环
//标准的模板题(虽然有很多解法)
#include<iostream>#include<cstdio>#include<cstring>#include<stack>using namespace std;const int maxn = 200000 + 100;int n;struct edge { int u,v; int next;}e[maxn];int head[maxn], tot = 0;int read() { int x = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9') { if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); } return x * f;}void add(int u, int v) { e[++tot] = (edge){u,v,head[u]}; head[u] = tot;}stack<int>q;int dfn[maxn],low[maxn],vis[maxn],cnt = 0,ans = 1<<29;void dfs(int x) { dfn[x] = low[x] = ++cnt; q.push(x); vis[x] = 1; for(int i = head[x]; i ; i = e[i].next) { int v = e[i].v; if(!dfn[v]) { dfs(v); low[x] = min(low[x], low[v]); } else if(vis[v]) { low[x] = min(low[x], dfn[v]); } } if(low[x] == dfn[x]) { int t = x,sum = 0; do{ vis[t] = 0; sum++; t = q.top(); q.pop(); } while(t != x); if(sum != 1) ans = min(ans,sum); }}void tarjan() { for(int i = 1; i <= n; i++) { if(!dfn[i]) dfs(i); }}int main() { n = read(); for(int i = 1; i <= n; i++) { int v = read(); add(i,v); } tarjan(); cout<<ans<<endl; return 0;}
应用
1.找环
//同上面例题
2.割边割点
//好吧,这个应该不考,不想写了
//QAQ
3.缩点
!!!!!!!这个很重要,缩了点就可以跑DAG了
(DP,蒟蒻瑟瑟发抖~~)–好吧我不会DP
但缩点还是会的
[HAOI2006]受欢迎的牛
最水的缩点T
#include<cstdio>#include<iostream>#include<stack>using namespace std;const int maxn = 100000 + 100;int n,m;struct edge { int u,v,next;}e[maxn * 2];int head[maxn],tot = 0;void add(int u, int v) { e[++tot] = (edge) {u,v,head[u]}; head[u] = tot;}stack<int>q;int pre[maxn],low[maxn],vis[maxn],cnt = 0,ctt = 0,tp[maxn],dis[maxn];void tarjan(int x) { pre[x] = low[x] = ++cnt; q.push(x); dis[x] = 1; for(int i = head[x]; i; i = e[i].next) { int v = e[i].v; if(!pre[v]) { tarjan(v); low[x] = min(low[x],low[v]); } else if(dis[v]) { low[x] = min(low[x],pre[v]); } } if(low[x] == pre[x]){ int t; ctt++; do{ t = q.top(); q.pop(); dis[t] = 0; //打标记 vis[t] = ctt; tp[ctt]++; }while(t != x); }}int d[maxn];int main() { cin>>n>>m; for(int i = 1; i <= m; i++) { int u,v; cin>>u>>v; add(u,v); } for(int i = 1; i <= n; i++) { if(!pre[i]){ tarjan(i); } } //注意此处不是for(int i = 1; i <= n; ++) —— for(int j = head[i]; j ; j = e[j].next) //否则TLE for(int i = 1; i <= m; i++) { if(vis[e[i].v] != vis[e[i].u]){ d[vis[e[i].u]]++; } } int tt,sum = 0; for(int i =1; i <= ctt; i++) { if(d[i] == 0) { sum++; tt = i; } } if(sum != 1){ cout<<'0'<<endl; return 0; } else{ cout<<tp[tt]<<endl; return 0; }}
阅读全文
1 0
- 蒟蒻复习之-----Tarjan
- 【复习记录】Tarjan
- 蒟蒻复习之-----Floyd
- 蒟蒻复习之-----LCA
- 蒟蒻复习之-----二分
- [复习][poj2186]Tarjan Popular Cows
- 图论复习之强连通分量以及缩点—Tarjan算法
- 蒟蒻复习之-----SPFA,dijkstra
- 蒟蒻复习之-----并查集
- 蒟蒻复习之-----最小生成树
- 蒟蒻复习之—–STL
- 蒟蒻复习之—–二进制
- 蒟蒻复习之—–数学
- hdu1269之tarjan
- LCA之TARJAN算法
- LCA之tarjan模板
- 蒟蒻复习之—–对拍
- Tarjan算法(蒟蒻专用)
- 递归与分治——排列问题
- Django 出现:Could not parse the remainder: 'date::'Y /m /d''
- Qt加载磁盘文件和对文件内容进行过滤
- MD5简单加密
- 单源最短路径算法(Dijkstra算法)
- 蒟蒻复习之-----Tarjan
- 在Linux下安装MySQL
- 文章获取与单词统计排序
- [bzoj4552][Tjoi2016&Heoi2016]排序 二分+线段树
- 河城荷取 二分答案 最大流
- 51Nod 1035 最长的循环节
- [java]创建新数组的三种方式
- 字符串的连接
- HBase之——Shell基础操作