tarjan算法求图中的强连通子图的个数。

 #include<iostream>

 #include<stack>
#include<queue>
#include<string>
#include<cstring>
#include<algorithm>
#include<cmath>
# define maxn
using namespace std;
vector<int>wakaka[maxn];
stack<int>q;
int low[maxn];
int dfn[maxn];
int vis[maxn];
int num,ans;
void tarjan(int u)//u始终代表父亲节点
{
low[u]=dfn[u]=++num;
q.push(u);
vis[u]=;
int len=wakaka[u].size();
for(int i=; i<len; i++)
{
int v=wakaka[u][i];
if(vis[v]==)
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
if(vis[v])
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
ans++;
int top;
do
{
top=q.top();
q.pop();
vis[top]=-;
}
while(u!=top);
}
}
int main()
{
int n,m;
while(cin>>n>>m&&(n+m))
{
for(int i=; i<=n; i++)
{
wakaka[i].clear();
}
ans=num=;
while(!q.empty())q.pop();
memset(vis,,sizeof(vis));
for(int i=; i<=m; i++)
{
int u,v;
cin>>u>>v;
wakaka[u].push_back(v);
}
for(int i=; i<=n; i++)
{
if(vis[i]==)
{
if(ans>=){
break;
}
tarjan(i);
}
}
if(ans==)
cout<<"Yes"<<endl;
else {
cout<<"No"<<endl;
}
}
return ;
}

 

tarjan算法缩点运算的使用具体事例

题目链接:http://poj.org/problem?id=2186

具体大意:假设有三头公牛a,b,c。a仰慕b,b仰慕c,那么这个c就是剩下的所有公牛的仰慕对象,然后这个题就是让你算出符合条件的公牛一共有多少头。

具体思路:首先,建成一个连通图,通过tarjan算法,然后对强连通子图进行缩点,对缩点后的“新”图来说,求出度为0的缩点中牛的数目。(这个题有一个坑点,就是条件是只要当前的这头牛被剩余的所有的牛仰慕就够了,它本身也可以再去崇拜别的牛,比如说 1  2 3构成一个强连通子图,输出结果应该是3,因为每一头牛都会被剩下的牛所仰慕。))

代码如下:

 #include<iostream>
#include<string>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<map>
#include<vector>
#include<stack>
#include<queue>
using namespace std;
#define maxn 50005
int low[maxn],dfn[maxn],vis[maxn],cnt[maxn],color[maxn],out[maxn];//low数组和dfn数组是tarjan算法的基本数组,vis数组是用来判断是否访问过的,cnt数组是用来存 染色后某一种具体颜色的点的个数,color数组是用来染色的,out数组是用来记录缩点之后,某一种颜色对应的出度
int num,ans;
vector<int>wakaka[maxn];
stack<int>q;
void tarjan(int u)
{
vis[u]=;
q.push(u);
low[u]=dfn[u]=++num;
int len=wakaka[u].size();
for(int i=; i<len; i++)
{
int v=wakaka[u][i];
if(vis[v]==)
{
tarjan(v);
low[u]=min(low[u],low[v]);
}
if(vis[v]==)
{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u])
{
int top;
ans++;
do
{
top=q.top();
q.pop();
vis[top]=-;
color[top]=ans//对同一个连通图里的字块进行染色;
}
while(top!=u);
}
} int main()
{
int n,m;
while(cin>>n>>m)
{
ans=num=;
while(!q.empty())q.pop();
for(int i=; i<=n; i++)
{
wakaka[i].clear();
}
memset(vis,,sizeof(vis));
memset(cnt,,sizeof(cnt));
memset(color,,sizeof(color));
memset(out,,sizeof(out));
for(int i=; i<=m; i++)
{
int u,v;
cin>>u>>v;
wakaka[u].push_back(v);
}
for(int i=; i<=n; i++)
{
if(vis[i]==)
{
tarjan(i);
}
}
for(int i=; i<=n; i++)
{
int t=color[i];
int len=wakaka[i].size();
for(int j=; j<len; j++)
{
// cout<<i<<" "<<wakaka[i][j]<<endl;
if(t!=color[wakaka[i][j]])
{
out[t]++;//判断染色后某一个强连通子图的出度
}
}
cnt[t]++;//记录某一个颜色下自快的个数
}
//cout<<ans<<endl<<color[1]<<endl<<color[2]<<endl<<color[3]<<endl;
int x=,temp;
for(int i=; i<=ans; i++)
{
// cout<<i<<" "<<out[i]<<" "<<cnt[i]<<endl;
if(out[i]==)
{
x++;
temp=cnt[i];
}
//cout<<temp<<endl;
}
if(x==)//只能有一个出度为0的缩点,如果有两个的话是肯定不成立的,打个比方,牛角,两边的端点都是出度为0,但是两边不互相承认对方为最强。
{
cout<<temp<<endl;
}
else
{
cout<<<<endl;
}
}
return ;
}

 

 

 

tarjan算法(求强连通子块,缩点)的更多相关文章

  1. HDU 1269 迷宫城堡 tarjan算法求强连通分量

    基础模板题,应用tarjan算法求有向图的强连通分量,tarjan在此处的实现方法为:使用栈储存已经访问过的点,当访问的点离开dfs的时候,判断这个点的low值是否等于它的出生日期dfn值,如果相等, ...

  2. [学习笔记] Tarjan算法求强连通分量

    今天,我们要探讨的就是--Tarjan算法. Tarjan算法的主要作用便是求一张无向图中的强连通分量,并且用它缩点,把原本一个杂乱无章的有向图转化为一张DAG(有向无环图),以便解决之后的问题. 首 ...

  3. Tarjan 算法求 LCA / Tarjan 算法求强连通分量

    [时光蒸汽喵带你做专题]最近公共祖先 LCA (Lowest Common Ancestors)_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili tarjan LCA - YouTube Tarj ...

  4. 【算法】Tarjan算法求强连通分量

    概念: 在有向图G中,如果两个定点u可以到达v,并且v也可以到达u,那么我们称这两个定点强连通. 如果有向图G的任意两个顶点都是强连通的,那么我们称G是一个强连通图. 一个有向图中的最大强连通子图,称 ...

  5. tarjan算法求强连通分量

    先上代码: #include <iostream> #include <cstring> #include <vector> #include <stack& ...

  6. tarjan 算法求强连通分量

    #include<bits/stdc++.h> #define ll long long using namespace std; const int P=1e6; ; ; const i ...

  7. Tarjan算法求有向图强连通分量并缩点

    // Tarjan算法求有向图强连通分量并缩点 #include<iostream> #include<cstdio> #include<cstring> #inc ...

  8. Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载)

    Tarjan算法应用 (割点/桥/缩点/强连通分量/双连通分量/LCA(最近公共祖先)问题)(转载) 转载自:http://hi.baidu.com/lydrainbowcat/blog/item/2 ...

  9. Tarjan求强连通分量,缩点,割点

    Tarjan算法是由美国著名计算机专家发明的,其主要特点就是可以求强连通分量和缩点·割点. 而强联通分量便是在一个图中如果有一个子图,且这个子图中所有的点都可以相互到达,这个子图便是一个强连通分量,并 ...

随机推荐

  1. 2018 ACM 网络选拔赛 青岛赛区

    一些题目的代码被网站吞了…… Problem B. Red Black Tree http://acm.zju.edu.cn/onlinejudge/searchProblem.do?contestI ...

  2. Day29--Python--缓冲区, 粘包

    tcp: 属于长连接,与一个客户端进行连接了以后,其他的客户端要等待.要想连接另外一个客户端,需要优雅地断开当前客户端的连接 允许地址重用:server.setsockopt(socket.SOL_S ...

  3. HTML学习笔记Day1

    一.网站建设流程 1.注册域名(网址) 2.租用空间(服务器) 3.网站建设 (1)确定网站主题(项目) (2)搜集材料(项目) (3)规划网站(UI) (4)制作页面(前端--后端) 4.网络推广 ...

  4. MySQL创建方法错误:This function has none of DETERMINISTIC, NO SQL

    创建function时 出错信息: ERROR 1418 (HY000): This function has none of DETERMINISTIC, NO SQL, or READS SQL ...

  5. sprignclou的zuul的实战

    idea启动集群服务: https://blog.csdn.net/love_dl_forever/article/details/78918181 http://www.scienjus.com/a ...

  6. 学习Docker之Dockerfile的命令

    使用Dockerfile去构建镜像好比堆积木.使用pom去构建maven项目一样,有异曲同工之妙,下面就把Dockerfile中主要的命令介绍一下. 组成部分 部分 命令 基础镜像信息 FROM 维护 ...

  7. java十进制转三十六进制

    import java.util.HashMap; public class Ten2Thirty { private static final String X36 = "01234567 ...

  8. jackson工具类 对象转字符串 -- 字符串转对象

    这个一个json的工具类.用的是jackson,当然还有谷歌的gosn,阿里的fastjson ,但是jackson的感觉还是最成熟(网上大神说的...) 实现的功能很简单,对象转字符串  字符串转简 ...

  9. Nlog日志组件简介

    NLog简介 NLog是一个简单灵活的.NET日志记录类库,NLog的API非常类似于log4net,配置方式非常简单.支持多种形式输出日志:文本文件.系统日志.数据库.控制台.邮箱等 1.NLog简 ...

  10. linux 内核模块makefile通用模板

    ifneq ($(KERNELRELEASE),)# 在 mylist 后面添加需要编译的模块数量 mylist=hello.o a.o# 为每一个模块添加所需的文件 hello-objs := ma ...