码迷,mamicode.com
首页 > 其他好文 > 详细

Popular Cows//强连通分支Kosaraju加缩点

时间:2018-06-24 00:43:36      阅读:167      评论:0      收藏:0      [点我收藏+]

标签:think   space   integer   强连通分量   pst   连通   ted   div   printf   

题目:

 

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 38415   Accepted: 15658

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.

 

思路:

 

代码:

#include <iostream>
#include <vector>
using namespace std;
const int size = 1e4 + 1;
vector<int> graph[size];
vector<int> reverse[size];
int order[size];//
int pos = 0;//用于order[]的索引
bool marked[size];
bool marked2[size];
int ans = 0;//连通分支数
int DAG[size];//分离强连通分量
int out[size];//DAG的出度,一共只有强连通分支数那么多个点

void init(int N)//初始化
{
    pos = ans = 0;
    for(int i = 1; i <= N; i++)
    {
        marked[i] = false;
        marked2[i] = false;
        graph[i].clear();
        reverse[i].clear();
        DAG[i] = 0;
        out[i] = 0;
    }
}

void dfsReverseOrder(int x)
{
    marked[x] = true;
    for(int i = 0; i < reverse[x].size(); i++)
    {
        if(!marked[reverse[x][i]])
            dfsReverseOrder(reverse[x][i]);
    }
    order[pos++] = x;
}

void dfs(int x)
{
    DAG[x] = ans;
    marked2[x]  = true;
    for(int i = 0; i < graph[x].size(); i++)
    {
        if(!marked2[graph[x][i]])
        {
            dfs(graph[x][i]);
        }
        else if(DAG[graph[x][i]] != DAG[x])//和计算出度有关
            out[ans] = 1;
    }
}

void Kosaraju(int N)
{
    for(int i = 1; i <= N; i++)
    {
        if(!marked[i])
            dfsReverseOrder(i);
    }
    pos--;

    for(; pos >= 0;pos--)
    {
        if(!marked2[order[pos]])
        {
            dfs(order[pos]);
            ans++;
        }
    }
}

int main()
{
    int N, M;
    int a, b;
    while(cin >> N >> M)
    {
        init(N);
        //输入
        for(int i = 0; i < M; i++)
        {
            cin >> a >> b;
            graph[a].push_back(b);
            reverse[b].push_back(a);    
        }
        Kosaraju(N);
        int count = 0;
        int flag;
        for(int i = 0; i < ans; i++)//找出度为0的强连通分支的个数
        {
            if(out[i] == 0)
            {
                count++;
                flag = i;
            }
        }
        int num = 0;
        if(count == 1)//若只有一个出度为0的强连通分支
        {
            for(int i = 1; i <= N; i++)//计算该强连通分支内点的个数
            {
                if(DAG[i] == flag)
                    num++;
            }
            printf("%d\n", num);
        }
        else 
            printf("%d\n", 0);
    }
    return 0;
}

 

Popular Cows//强连通分支Kosaraju加缩点

标签:think   space   integer   强连通分量   pst   连通   ted   div   printf   

原文地址:https://www.cnblogs.com/w-j-c/p/9218978.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!