强连通分量分解
2016-04-02 22:46
232 查看
#include "iostream" #include "stack" #include "vector" #include "string.h" using namespace std; const MAX_V = 100; vector<int> G[MAX_V]; //图的邻接表 vector<int> rG[MAX_V]; //反向图的邻接表 int visit[MAX_V]; //访问标记 int cmp[MAX_V]; //所属强连通分量的拓扑排序 vector<int> vs; //后序遍历的顶点列表 int V = 12; //顶点数 void addEdge(int from, int to) { G[from].push_back(to); rG[to].push_back(from); } void dfs(int v) { visit[v] = 1; for(int i=0; i<G[v].size(); i++) if(!visit[G[v][i]]) dfs(G[v][i]); vs.push_back(v); } void rdfs(int v, int k) { visit[v] = 1; cmp[v] = k; for(int i=0; i<rG[v].size(); i++) if(!visit[rG[v][i]]) rdfs(rG[v][i], k); } int scc() { memset(visit, 0, sizeof(visit)); vs.clear(); int i; for(i=0; i<V; i++) if(!visit[i]) dfs(i); memset(visit, 0, sizeof(visit)); int k = 0; for(i=vs.size()-1; i>=0; i--) //越是尾部的结点编号越小 if(!visit[vs[i]]) rdfs(vs[i], k++); return k; } int main() { int G1[12][12] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0} }; int i, j; for(i=0; i<V; i++) for(j=0; j<V; j++) if(G1[i][j] == 1) addEdge(i, j); cout << "压缩图的顶点个数:" << scc() << endl; cout << "新的顶点编号" << endl; for(i=0; i<V; i++) cout << i+1 << ": " << cmp[i]+1 << endl; return 0; }
相关文章推荐
- 算法导论—Trie树
- Android WebView常见问题及解决方案汇总
- 字符串反转的进一步应用----单词反转
- day24 订单删除 & 打印销量排行榜 & 在线支付
- 通过udl文件得到连接字符串
- 重载方法调用精确匹配问题
- OSChina 周日乱弹 ——我18岁了都没睡过男人
- 活动选择
- C++实践参考:IP地址类
- 编码又闹出了小问题
- 2006年清华大学计算机研究生机试真题
- 笔试题——对称二叉树
- SP5000系列烧录器大小端转换C语言实现
- 数据结构知识基础之指针
- 装船问题
- viewpager最后一个view滑动开启另一个activity等的方法
- 资源
- 学习 个人总结
- 人脸美化随笔2——美化算法总结
- 正则表达式---简化字符串操作