POJ2186 Popular Cows(强连通分量)
2016-01-24 20:00
211 查看
题目问一个有向图所有点都能达到的点有几个。
先把图的强连通分量缩点,形成一个DAG,那么DAG“尾巴”(出度0的点)所表示的强连通分量就是解,因为前面的部分都能到达尾巴,但如果有多个尾巴那解就是0了,因为尾巴间达到不了。判断是否有多个尾巴,可以从最后一个强连通分量中的某一个点出发看能否在逆图上遍历完其他点。
因为用到了逆图,所以直接用Kosaraju算法。
先把图的强连通分量缩点,形成一个DAG,那么DAG“尾巴”(出度0的点)所表示的强连通分量就是解,因为前面的部分都能到达尾巴,但如果有多个尾巴那解就是0了,因为尾巴间达到不了。判断是否有多个尾巴,可以从最后一个强连通分量中的某一个点出发看能否在逆图上遍历完其他点。
因为用到了逆图,所以直接用Kosaraju算法。
#include<cstdio> #include<cstring> #include<vector> #include<algorithm> using namespace std; #define MAXM 111111 #define MAXN 11111 struct Edge{ int v,next; }edge[MAXM]; int NE,head[MAXN],rhead[MAXN]; void addEdge(int u,int v){ edge[NE].v=v; edge[NE].next=head[u]; head[u]=NE++; edge[NE].v=u; edge[NE].next=rhead[v]; rhead[v]=NE++; } int belong[MAXN]; bool vis[MAXN]; vector<int> post; void dfs(int u){ vis[u]=1; for(int i=head[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue; dfs(v); } post.push_back(u); } void rdfs(int u,int k){ vis[u]=1; belong[u]=k; for(int i=rhead[u]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue; rdfs(v,k); } } int rdfs(int u){ int res=1; vis[u]=1; for(int i=rhead[i]; i!=-1; i=edge[i].next){ int v=edge[i].v; if(vis[v]) continue; res+=rdfs(v); } return res; } int scc(int n){ memset(vis,0,sizeof(vis)); post.clear(); for(int i=1; i<=n; ++i){ if(!vis[i]) dfs(i); } memset(vis,0,sizeof(vis)); int k=0; for(int i=post.size()-1; i>=0; --i){ int v=post[i]; if(!vis[v]) rdfs(v,++k); } memset(vis,0,sizeof(vis)); for(int i=1; i<=n; ++i){ if(belong[i]==k){ if(rdfs(i)!=n) return 0; break; } } int res=0; for(int i=1; i<=n; ++i){ if(belong[i]==k) ++res; } return res; } int main(){ memset(head,-1,sizeof(head)); memset(rhead,-1,sizeof(rhead)); int n,m,a,b; scanf("%d%d",&n,&m); while(m--){ scanf("%d%d",&a,&b); addEdge(a,b); } printf("%d",scc(n)); return 0; }
相关文章推荐
- Linux 平台设备驱动模型
- Linux命令详解 — time
- linux文本模式下使用PPPOE拨号ADSL上网的方法
- nginx日志通过rsyslog传入到日志服务器指定目录
- linux伙伴系统
- opencv学习笔记(二十三)——相机标定原理详解
- 使用gcc和cmake编译工具编辑opencv例子
- Windwos下安装Hadoop
- OpenGL相关
- nova虚拟机打不开console
- Ceph rbd cmd练习
- 【Linux运维-集群技术进阶】CentOS7添加虚拟IP(VIP)
- Nginx的安装
- Linux用户态编程-伪终端(一)
- Nginx服务器
- 2015年OpenWRT路由器挂载RT3070 USB无线网卡
- 浅谈初次搭建nginx+php+mysql遇到的问题
- jdk、Tomcat的安装及配置
- flock shell script 使用速记
- 【未完】yum源解析,配置