tarjan通俗易懂题
洛谷2661
https://www.luogu.org/problemnew/show/P2661
分析:求缩点后成环中,环大小最小的size
- #include<bits/stdc++.h>
- using namespace std;
- const int M=2e5+;
- vector<int>e[M];
- int vis[M],dfn[M],low[M],cnt,ans=M;
- stack<int>S;
- void tarjan(int u){
- dfn[u]=low[u]=++cnt;
- vis[u]=;
- S.push(u);
- for(int i=;i<e[u].size();i++){
- int v=e[u][i];
- if(!dfn[v]){
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v])
- low[u]=min(low[u],dfn[v]);
- }
- if(low[u]==dfn[u]){
- int countt=;
- while(true){
- int t=S.top();
- S.pop();
- vis[t]=;
- countt++;
- if(t==u)
- break;
- }
- if(countt>)
- ans=min(ans,countt);
- }
- }
- int main(){
- int n;
- scanf("%d",&n);
- for(int i=;i<=n;i++){
- int x;
- scanf("%d",&x);
- e[i].push_back(x);
- }
- for(int i=;i<=n;i++){
- if(!dfn[i])
- tarjan(i);
- }
- cout<<ans;
- return ;
- }
https://www.luogu.org/problemnew/show/P1726
分析:还是求环的大小,不过要在存路径时加些操作
- #include<iostream>
- #include<cstdio>
- #include<algorithm>
- #include<cstring>
- #include<stack>
- #include<vector>
- using namespace std;
- const int M=5e4+;
- int dfn[M],low[M],vis[M],a[M],b[M],cnt;
- vector<int>e[M];
- stack<int>S;
- int ans;
- void tarjan(int u){
- dfn[u]=low[u]=++cnt;
- vis[u]=;
- S.push(u);
- for(int i=;i<e[u].size();i++){
- int v=e[u][i];
- if(!dfn[v]){
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v])
- low[u]=min(low[u],dfn[v]);
- }
- if(low[u]==dfn[u]){
- int countt=;
- while(true){
- int t=S.top();
- S.pop();
- vis[t]=;
- a[countt++]=t;
- if(t==u)
- break;
- }
- if(ans<=countt){
- sort(a,a+countt);
- if(ans==countt){
- int flag=;
- for(int i=;i<countt;i++)
- if(a[i]<b[i]){
- flag=;
- break;
- }
- else if(a[i]>b[i])
- break;
- if(flag==)
- for(int i=;i<countt;i++)
- b[i]=a[i];
- }
- else{
- for(int i=;i<countt;i++)
- b[i]=a[i];
- }
- ans=countt;
- }
- }
- }
- int main(){
- int n,m;
- scanf("%d%d",&n,&m);
- for(int i=;i<=m;i++){
- int u,v,t;
- scanf("%d%d%d",&u,&v,&t);
- if(t==)
- e[u].push_back(v);
- else
- e[u].push_back(v),e[v].push_back(u);
- }
- for(int i=;i<=n;i++)
- if(!dfn[i])
- tarjan(i);
- printf("%d\n",ans);
- for(int i=;i<ans;i++){
- printf("%d ",b[i]);
- }
- return ;
- }
https://www.luogu.org/problemnew/show/P2341
分析:所求量一定为经缩点后唯一出度为0的强联通分量的大小
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<stack>
- #include<vector>
- using namespace std;
- const int M=1e4+;
- const int N=5e4+;
- vector<int>e[M];
- int out[M],in[M],dfn[M],low[M],vis[M],sz[N],cnt,tot,cmp[N];
- stack<int>S;
- void tarjan(int u){
- low[u]=dfn[u]=++cnt;
- vis[u]=;
- S.push(u);
- for(int i=;i<e[u].size();i++){
- int v=e[u][i];
- if(!dfn[v]){
- tarjan(v);
- low[u]=min(low[u],low[v]);
- }
- else if(vis[v])
- low[u]=min(low[u],dfn[v]);
- }
- if(dfn[u]==low[u]){
- int countt=;
- tot++;
- while(true){
- int t=S.top();
- S.pop();
- vis[t]=;
- cmp[t]=tot;
- countt++;
- if(t==u)
- break;
- }
- sz[tot]=countt;
- }
- }
- int main(){
- int n,m;
- scanf("%d%d",&n,&m);
- int u,v;
- for(int i=;i<=m;i++){
- scanf("%d%d",&u,&v);
- e[u].push_back(v);
- }
- for(int i=;i<=n;i++)
- if(!dfn[i])
- tarjan(i);
- int sum=;
- for(int i=;i<=n;i++)
- for(int j=;j<e[i].size();j++){
- int v=e[i][j];
- if(cmp[i]!=cmp[v])
- out[cmp[i]]++,in[cmp[v]]++;
- }
- int countt=,sign;
- for(int i=;i<=tot;i++)
- if(out[i]==)
- countt++,sign=i;
- if(countt>)
- return puts(""),;
- printf("%d\n",sz[sign]);
- return ;
- }
tarjan通俗易懂题的更多相关文章
- UOJ #146. 【NOIP2015】信息传递 连通分量 tarjan模板题
http://uoj.ac/problem/146 题解:强连通分量 tarjan模板题.同时试了一下codeblock #include<bits/stdc++.h> using nam ...
- POJ 2186:Popular Cows Tarjan模板题
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 25945 Accepted: 10612 De ...
- Tarjan 做题总结
这两天Tarjan复习完后把题做了做.洛谷题单<图的连通性>已经做得差不多了.大部分是Tarjan的题,所以写一篇小总结. T1 [模板] 缩点 不多bb.我已经写过关于Tarjan模板的 ...
- PAT (Top Level) Practise 1008 Airline Routes(Tarjan模版题)
1008. Airline Routes (35) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue Given a ...
- 有向图强连通分支的Tarjan算法讲解 + HDU 1269 连通图 Tarjan 结题报告
题目很简单就拿着这道题简单说说 有向图强连通分支的Tarjan算法 有向图强连通分支的Tarjan算法伪代码如下:void Tarjan(u) {dfn[u]=low[u]=++index//进行DF ...
- Tarjan模板题——牛的舞会
题目描述 约翰的N (2 <= N <= 10,000)只奶牛非常兴奋,因为这是舞会之夜!她们穿上礼服和新鞋子,别 上鲜花,她们要表演圆舞. 只有奶牛才能表演这种圆舞.圆舞需要一些绳索和一 ...
- Tarjan水题系列(5):最大半连通子图 [ZJOI2007 luogu P2272]
题目 大意: 缩点后转为求最长链的长度和最长链的个数 思路: 看懂题就会做系列 长度和个数都可以拓扑排序后DP求得 毕竟是2007年的题 代码: 如下 #include <cstdio> ...
- Tarjan水题系列(4):HAOI2010 软件安装
题目: 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为M计算机上,使得这些软件的价值尽可能大(即Vi的和最大). ...
- Tarjan水题系列(3):HNOI2006 潘多拉的魔盒
题目: 链接 大意: 盒子与盒子之间的关系构成一个有向图 求图上包含节点数最多的路径的节点数 思路: 有向图上求包含节点数最多的路径的节点数 可直接使用tarjan缩点后拓扑dp求得 在此不赘述 此题 ...
随机推荐
- [转]Log4j使用总结
Log4j使用总结 一.介绍 Log4j是Apache的一个开放源代码项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台.文件.GUI组件.甚至是套接口服务 器.NT的事件记录器. ...
- JS基础——脚本位置、数据类型、函数作用域
(一)脚本位置 JavaScript是嵌套到浏览器里的脚本语言:可放在3个位置: 1.写在头部(head里) <head> <meta charset="UTF-8& ...
- 因子分析和PCA总结
因子分析和PCA 定义 因子分析就是数据降维工具.从一组相关变量中删除冗余或重复,把相关的变量放在一个因子中,实在不相关的因子有可能被删掉.用一组较小的“派生”变量表示相关变量,这个派生就是新的因子. ...
- JavaScript—暂告,小节
Javastript 的学习告一段落了.虽然还有更多的:爬虫 什么的 但是和我在学校的相比 要扎实许多.知道了兼容性 面向对象,闭包.....一些细节的用法. 虽然以后可能很少用到.可是我觉得 ...
- Linux-异步IO
1.何为异步IO (1).几乎可以这么认为:异步IO就是操作系统用软件实现的一套中断响应系统. (2).异步IO的工作方法:我们当前进程注册一个异步IO事件(使用signal注册一个信号SIGIO的处 ...
- PAT Advanced 1051 Pop Sequence (25) [栈模拟]
题目 Given a stack which can keep M numbers at most. Push N numbers in the order of 1, 2, 3, -, N and ...
- RE数组开多大?
#include<iostream> using namespace std; ][]; int main() { int n, m; ; i <= ; i++) { a[][i] ...
- sol - 0x63
[例题]巡逻 注意到K只能是1或2,也就是说只能建0/1/2条新道路 我们分类讨论 当修建0条新道路的时候, 执行遍历会恰好遍历到每条边2次,答案为2*(n-1) 当修建1条新道路的时候, 我们设新道 ...
- ES6之模块化
本文介绍ES6实现模块化的方法:使用import和export. 导入的时候需不需要加大括号的判断:1.当用export default people导出时,就用 import people 导入(不 ...
- Django_前介
Django 1.软件框架 一个公司是由公司中的各部部门来组成的,每一个部门拥有特定的职能,部门与部门之间通过相互的配合来完成让公司运转起来. 一个软件框架是由其中各个软件模块组成的,每一个模 ...