poj2186我的第一个强连通题目
2013-11-01 20:43
288 查看
#include <iostream> #include <cstdio> #include <cstring> #include <stack> #define debug puts("here") using namespace std; const int M = 10009; const int N = 50009; struct node { int v; int next; }num ; int sccf[M]; int low[M]; int dfn[M]; bool ins[M]; int adj[M]; int rdu[M]; int scc, index; stack<int>s; int n, m; void init() { scc = 0; index = 1; memset(dfn, 0, sizeof(dfn)); memset(low, 0, sizeof(low)); memset(adj, -1, sizeof(adj)); memset(ins, false, sizeof(ins)); memset(sccf, 0, sizeof(sccf)); } void Tarjan(int u) { int v; low[u] = dfn[u] = index++; s.push(u); ins[u] = true; for(int k = adj[u]; k != -1; k = num[k].next) { v = num[k].v; if(dfn[v] == 0) { Tarjan(v); if(low[v] < low[u]) { low[u] = low[v]; } } else if(ins[v]&& low[v] < low[u]) { low[u] = low[v]; } } if(low[u] == dfn[u]) { scc++; do { v = s.top(); s.pop(); ins[v] = false; sccf[v] = scc;//此步进行所谓的缩点; }while(u != v); } } int getsuperpopularnum() { memset(rdu, 0, sizeof(rdu)); int v, u; int cnt = 0; int cn ; memset(cn, 0, sizeof(cn)); for(u = 1; u <= n; u++) { cn[sccf[u]]++; //同一缩点内的点数; for(int k = adj[u]; k != -1; k = num[k].next) { v = num[k].v; if(sccf[v] != sccf[u]) { rdu[sccf[u]]++; } } } for(int i = 1; i <= scc; i++) { if(rdu[i] == 0) { cnt++; v = i; } } return (cnt == 1)? cn[v] : 0;//如果出度为零的点多以一个, 则无解; } int main() { int a, b; int e = 0; init(); cin>>n>>m; for(int i = 1; i <= m; i++) { cin>>a>>b; num[e].v = b; //通过e 找到a 的下一个边b; num[e].next = adj[a];//存a可到达的下一个边; adj[a] = e;//通过adj[a]找到节点e e++; } for(int i = 1; i <= n; i++) { if(dfn[i] == 0) { Tarjan(i); } } printf("%d\n", getsuperpopularnum()); return 0; }
详细资料 :https://www.byvoid.com/blog/scc-tarjan
相关文章推荐
- 【剑指Offer面试编程题】题目1283:第一个只出现一次的字符--九度OJ
- 题目是:写一个函数,返回一个数组中所有元素被第一个元素除的结果
- poj2186 Popular Cows --- 强连通
- 题目1505:两个链表的第一个公共结点
- 【九度】题目1505:两个链表的第一个公共结点
- 第18题: 题目:n个数字(0,1,„,n-1)形成一个圆圈,从数字0开始, 每次从这个圆圈中删除第m个数字(第一个为当前数字本身,第二个为当前数字的下一个数字)。 当一个数字删除后,从被删除数字的下
- 【剑指Offer面试编程题】题目1283:第一个只出现一次的字符--九度OJ
- 剑指offer题目描述 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
- 纪念自己用java写的第一个题目
- 第一个python作业题目以及代码
- 题目:1<n<9, n个猴子,第一个猴子扔一个,然后平均分为n份,拿一份; 第二个猴子扔一个,然后平均分n份,拿一份。。。依次到最后一个猴子也是扔一个,均分n份,拿一份。
- [九度OnlineJudge][剑指Offer]题目1283:第一个只出现一次的字符
- HDU 1285 确定比赛名次(第一个拓扑排序题目)
- 题目:输入两个链表,找出它们的第一个公共结点
- 剑指offer- 题目1505:两个链表的第一个公共结点 (2014.1.1)
- 九度_题目1283:第一个只出现一次的字符
- 九度题目1505:两个链表的第一个公共结点
- 九度OJ-题目1505:两个链表的第一个公共结点
- 【程序35】 ArrayChange.java 题目:输入数组,最大的与第一个元素交换,最小的与最后一个元素交换,输出数组。
- 剑指offer面试题目:第一个只出现一次的字符