POJ 2186 Popular Cows(强连通分量)
来源:互联网 发布:ipad矢量图软件 编辑:程序博客网 时间:2024/05/22 15:10
题目大意:
给定一个有向图,求有多少个顶点是由任何顶点出发都可达的。
补充1:
有向无环图中唯一出度为0的点,一定可以由任何点出发均可达(由于无环,所以从任何点出发往前走,必然终止于一个出度为0的点)
解题思路:
1、求出所有的强连通分量
2、每个强连通分量缩成一点,则形成一个有向无环图DAG
3、DAG上面如果有唯一的出度为0的点,则该点能被所有的点可达。那么该点所代表的连通分量上的所有的原图中的点,都能被原图中的所有点可达,则该连通分量的点数,就是答案
4、DAG上面如果有不止一个出度为0的点,则这些点互相不可达,原问题无解,答案为0
补充2:
Korasaju算法求有向图强连通分支
begin
1.深度优先遍历G,算出每个结点u的访问结束时间f[u],起点如何选择无所谓。
2.深度优先遍历G的转置图GT,选择遍历的起点时,按照结点的访问结束时间从大到小进行。遍历的过程中,一边遍历,一边给结点做分类标记,每找到一个新的起点,分类标记值就加1。
3.第2步中产生的标记值相同的结点构成深度优先森林中的一棵树,也即一个强连通分量
end
算法复杂度分析(邻接表)
深度优先搜索的复杂度:O(V+E)
计算GT的复杂度:0或者O(V+E)
总的复杂度:O(V+E)
代码:
#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#define M 10005using namespace std;struct Cow{ int th; int starT; int endT; int mark;}cow[M];vector <int> adj[M];vector <int> adjT[M];int n, m, t, lable;int vis[M];void dfs1(int v) { //深度优先遍历G,算出每个结点的结束时间 vis[v] = 1; for(int i=0; i<adj[v].size(); i++) { if(vis[adj[v][i]] == 0) { cow[adj[v][i]].starT = t++; vis[adj[v][i]] = 1; dfs1(adj[v][i]); cow[adj[v][i]].endT = t++; } } return ;}void dfs2(int v) { //深度优先遍历GT,做分类标记 vis[v] = 1; for(int i=0; i<adjT[v].size(); i++) { if(vis[adjT[v][i]] == 0) { cow[adjT[v][i]].mark = lable; vis[adjT[v][i]] = 1; dfs2(adjT[v][i]); } }}int cmp1(Cow c1, Cow c2) { return c1.endT > c2.endT;}int main() { int i, j, k; int a, b; while(~scanf("%d%d", &n, &m)) { memset(adj, 0, sizeof(adj)); memset(adjT, 0, sizeof(adjT)); for(i=0; i<n; i++) { adj[i].clear(); adjT[i].clear(); } for(i=0; i<m; i++) { scanf("%d%d", &a, &b); a--; b--; adj[a].push_back(b); //原图 adjT[b].push_back(a); //转置图 } t = 1; memset(vis, 0, sizeof(vis)); for(i=0; i<n; i++) { cow[i].th = i; if(vis[i] == 0) { cow[i].starT = t++; dfs1(i); cow[i].endT = t++; } } sort(cow, cow+n, cmp1); lable = 1; memset(vis, 0, sizeof(vis)); for(i=0; i<n; i++) { if(vis[cow[i].th] == 0) { cow[cow[i].th].mark = lable; dfs2(cow[i].th); lable ++; } } int tmpA[M]; memset(tmpA, 0, sizeof(tmpA)); for(i=0; i<n; i++) { //标记缩点后的点的出度情况 for(j=0; j<adj[cow[i].th].size(); j++) { if(cow[cow[i].th].mark != cow[adj[cow[i].th][j]].mark) { tmpA[cow[cow[i].th].mark] = 1; } } } int ans = 0; int ansN = 0; //统计缩点后的优先无环图的入度为0的点的个数 for(i=1; i<lable; i++) { if(tmpA[i] == 0) { ans = i; ansN ++; } } if(ansN > 1) { printf("0\n"); continue; } int res = 0; for(i=0; i<n; i++) { if(cow[i].mark == ans) { res ++; } } printf("%d\n", res); } return 0;}
0 0
- POJ 2186-Popular Cows ---强连通分量
- POJ 2186 Popular Cows / 强连通分量
- POJ 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows 强连通分量
- poj 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows(强连通分量)
- poj 2186 Popular Cows 【强连通分量】
- |poj 2186|强连通分量|Popular Cows
- poj 2186 Popular Cows 强连通分量
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- POJ 2186 Popular Cows(强连通分量)
- POJ 2186 Popular Cows (强连通分量)
- poj 2186 Popular Cows(强连通分量)
- TextView显示系统时间(秒针变化)
- ios与js交互,获取webview完整url,title,获取元素并赋值跳转
- 『IOS』ios nil、NULL和NSNull 的使用
- 指针函数与函数指针的区别
- [Coursera][Stanford] Machine Learning Week 3
- POJ 2186 Popular Cows(强连通分量)
- 仔细确认当前this对象是否是你所想指定的元素
- PHP中$_SERVER['HTTP_REFERER']的反盗链使用
- 二分图的简单介绍及相关题目
- ssh整合系列博客——(2)spring和hibernate整合的异常解决
- Could not execute JDBC batch update
- 常见图片格式简单分析总结--JPG、PNG、GIF、BMP
- SecureCRT常用命令
- 创建.NET服务