POJ 2186 Kosaraju算法 强连通分量

原创 2016年08月30日 21:33:03

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
  • u012846486
  • 2014年08月20日 17:37
  • 1948

强连通分量 的 Kosaraju算法

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

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

本文提纲: 问题描述 Kosaraju 算法 问题描述: 什么是强连通分量(StronglyConnected Component)(或者,被称为强...
  • qq1263292336
  • qq1263292336
  • 2015年12月07日 16:20
  • 482

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

这两个算法其实都非常简单,其中tarjan算法只需进行一次dfs,更为高效。但我更喜欢kosaraju算法,因为这个算法的思考过程更加巧妙。 tarjan算法的思想非常简单直观,随便找篇教程就很容易...
  • u011589125
  • u011589125
  • 2014年11月29日 10:28
  • 1747

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

有向图的强连通分量 SCC: 在有向图G中,如果两个顶点间相互可达,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。非强连通有向图的极...
  • STILLxjy
  • STILLxjy
  • 2017年04月18日 19:40
  • 634

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

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

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

强连通分量分解 对于一个有向图顶点的子集S,如果在S内任取两个顶点u和v,都能找到一条从u到v的路径,那么 就称S是强连通的。如果在强连通的顶点集合S中加入其他任意顶点集合后,它都不再是强连通的, 那...
  • update7
  • update7
  • 2017年04月23日 19:52
  • 49064

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

题意:有N头牛,他们之间有
  • u012139398
  • u012139398
  • 2014年11月23日 22:24
  • 368

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

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

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

在有向图G中,如果两个顶点vi,vj间有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的任意两个顶点都强连通...
  • serena_0916
  • serena_0916
  • 2016年12月09日 21:47
  • 789
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:POJ 2186 Kosaraju算法 强连通分量
举报原因:
原因补充:

(最多只允许输入30个字)