博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
消息扩散(强连通分量)
阅读量:5051 次
发布时间:2019-06-12

本文共 1378 字,大约阅读时间需要 4 分钟。

首先做一遍tarjan

然后枚举每个边判断是否在同一个连通块内

在新图上跑一边入度

若入度为0,ans累计

输出即可

#include
using namespace std;const int N=2e7+7;int m,n,k,p,idx,cnt,num,ans;struct node{ int nx,to;} e[N];bool vis[N];stack
s;int head[N],dfn[N],low[N],sum[N],color[N],in[N];void add_edge(int a,int b){ cnt++;e[cnt].to=b;e[cnt].nx=head[a];head[a]=cnt;}void paint(int x){ s.pop(); color[x]=num; sum[num]++; vis[x]=false;}void tarjan(int x){ dfn[x]=low[x]=++idx; s.push(x);vis[x]=true; for (int i=head[x];i;i=e[i].nx) { int y=e[i].to; if (!dfn[y]) { tarjan(y); low[x]=min(low[x],low[y]); } else if (vis[y]) low[x]=min(low[x],dfn[y]); } if (dfn[x]==low[x]) { num++; while (s.top()!=x) { int t=s.top(); paint(t); } paint(x); }}int main(){ scanf("%d%d",&n,&m); for (int i=1;i<=m;i++) { int x,y; scanf("%d%d",&x,&y); add_edge(x,y); } for (int i=1;i<=n;i++) if (!dfn[i]) tarjan(i); for (int i=1;i<=n;i++) { for (int j=head[i];j;j=e[j].nx) { int y=e[j].to; if (color[i]==color[y]) continue; in[color[y]]++; } } for (int i=1;i<=num;i++) if (in[i]==0) ans++; printf("%d",ans); return 0; }

 

转载于:https://www.cnblogs.com/Hale522520/p/10626788.html

你可能感兴趣的文章
Kubernetes 运维学习笔记
查看>>
并查集 经典 畅通工程
查看>>
Spark MLlib 之 Naive Bayes
查看>>
php修改SESSION的有效生存时间
查看>>
spring security 11种过滤器介绍
查看>>
Hibernate一对多、多对一关联
查看>>
一、记录Git使用中遇到的问题及解决方法
查看>>
学习网址
查看>>
前端表格插件datatables
查看>>
内部类
查看>>
树链剖分入门
查看>>
图解算法时间复杂度
查看>>
UI_搭建MVC
查看>>
一个样例看清楚JQuery子元素选择器children()和find()的差别
查看>>
代码实现导航栏分割线
查看>>
Windows Phone开发(7):当好总舵主 转:http://blog.csdn.net/tcjiaan/article/details/7281421...
查看>>
VS 2010打开设计器出现错误
查看>>
SQLServer 镜像功能完全实现
查看>>
Vue-详解设置路由导航的两种方法
查看>>
一个mysql主从复制的配置案例
查看>>