# POJ 2186 Kosaraju算法 强连通分量

Popular Cows
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 30842 Accepted: 12529
Description

Every cow’s dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is
popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.
Input

• Line 1: Two space-separated integers, N and M

• Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.
Output

• Line 1: A single integer that is the number of cows who are considered popular by every other cow.
Sample Input

3 3
1 2
2 1
2 3
Sample Output

1
Hint

Cow 3 is the only cow of high popularity.
Source

USACO 2003 Fall

//http://poj.org/problem?id=2186

//先对原图G进行dfs搜索,得到各个点搜索完成的顺序,之后对逆图H进行dfs搜索,从最晚完成搜索的点开始,删除记录能够遍历到的点,这些点构成一个强连通分量.得到所有强连通分量后,把他们各自抽象成一个点,形成一个有向无环图,在该图上寻找出度为0的点.如果仅有一个出度为0的点,则该点被所有点指向,答案为该强连通分量的大小.如果有多个出度为0的点,则这些点无法互相可达,无解,答案为0.
//有向无环图(DAG)保证至少存在一个出度为0的点.
#include <stdio.h>
#include <string>
#include <cstring>
#include <queue>
#include <algorithm>
#include <functional>
#include <vector>
#include <iomanip>
#include <math.h>
#include <iostream>
#include <sstream>
#include <stack>
#include <set>
#include <bitset>
using namespace std;
typedef long long ll;
const int MAX=10005;
int N,M,a,b,Cnt;
int Num[MAX],Tree[MAX],OutDgree[MAX];
vector<int> G[MAX],H[MAX],F;
bool Mark1[MAX],Mark2[MAX];
void dfs1(int x)
{
Mark1[x]=true;
for (int i=0; i<(int)G[x].size(); i++)
if (!Mark1[G[x][i]])
dfs1(G[x][i]);
F.push_back(x);
}
void dfs2(int x)
{
Mark2[x]=true;
Num[x]=Cnt;         //点x的连通分量编号为Cnt
Tree[Cnt]+=1;      //编号为Cnt的连通分量大小+1
for (int i=0; i<(int)H[x].size(); i++)
if (!Mark2[H[x][i]])
dfs2(H[x][i]);
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
while (cin>>N>>M)
{
memset(Mark1,false,sizeof(Mark1));
memset(Mark2,false,sizeof(Mark2));
memset(Num,0,sizeof(Num));
memset(Tree,0,sizeof(Tree));
memset(OutDgree,0,sizeof(OutDgree));
Cnt=0;
F.clear();
for (int i=0; i<MAX; i++)
{
G[i].clear();
H[i].clear();
}
for (int i=0; i<M; i++)
{
cin>>a>>b;
G[a].push_back(b);
H[b].push_back(a);
}
for (int i=1; i<=N; i++)
{
if (!Mark1[i])
dfs1(i);
}
for (int i=(int)F.size()-1; i>=0; i--)
{
if (!Mark2[F[i]])
{
Cnt++;
dfs2(F[i]);
}
}
for (int i=1;i<=N;i++)
{
for (int j=0;j<(int)G[i].size();j++)
{
if (Num[i]!=Num[G[i][j]])
OutDgree[Num[i]]+=1;
}
}
int temp=0,Ans=0;
for (int i=1;i<=Cnt;i++)
{
if (!OutDgree[i])
temp++,Ans=i;
}
cout<<(temp>1?0:Tree[Ans])<<endl;
}
return 0;
}


• 本文已收录于以下专栏：

## POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 96...
• u012846486
• 2014年08月20日 17:37
• 1948

## 强连通分量 的 Kosaraju算法

1. 定义 在有向图G中，如果两个顶点vi，vj有一条从vi到vj的有向路径，同时还有一条从vj到vi的路径，则称两个顶点强连通。如果有向图G中的每对顶点都强连通，称G是一个强连通图。有向图的极大强连...
• woniu317
• 2014年04月14日 09:52
• 1582

## 求解强连通分量算法之---Kosaraju算法

• qq1263292336
• 2015年12月07日 16:20
• 482

## 两种强连通分量算法——tarjan和kosaraju

• u011589125
• 2014年11月29日 10:28
• 1747

## 有向图的强连通分量Kosaraju算法 和 Tarjan算法思维详解及代码模板

• STILLxjy
• 2017年04月18日 19:40
• 634

## 有向图强连通分量的Tarjan算法和Kosaraju算法

[有向图强连通分量] 在有向图G中，如果两个顶点间至少存在一条路径，称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通，称G是一个强连通图。非强连通图有向图的极...
• txl16211
• 2014年08月16日 20:31
• 691

## Kosaraju算法求有向强连通分量,缩点后是DAG的拓扑序列(从小到大)

• update7
• 2017年04月23日 19:52
• 49064

## POJ 2186 Popular Cows 强连通分量 Kosaraju算法

• u012139398
• 2014年11月23日 22:24
• 368

## poj 2186(强连通分量的kosaraju算法)

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23420   ...
• my_acm
• 2014年08月18日 20:59
• 477

## 有向图的强连通分支算法kosaraju（C语言实现)

• serena_0916
• 2016年12月09日 21:47
• 789

举报原因： 您举报文章：POJ 2186 Kosaraju算法 强连通分量 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)