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

题目:

Popular Cows

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;
}

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

时间: 2024-10-12 11:11:04

Popular Cows//强连通分支Kosaraju加缩点的相关文章

POJ2186 Popular Cows【Kosaraju】【强连通分量】

Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24266Accepted: 9954 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 <= 5

Popular Cows 强连通(kosaraju)

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 30652   Accepted: 12439 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 &

POJ 2186 - Popular Cows - 强连通分量,缩点

题目大意: 给定一个含N个点.M条边的有向图,求其中有多少个点,可以由其他任意一点出发到达它? N<=1e4,M<=5e4. 为了描述和编程简便,我们建立原图的反图,这样问题转化为:有多少个点满足从它出发可以到达其他任意一点. 若无特殊说明,以下所指的图均为反图. 引理1:满足条件的所有点必然在同一强连通分量内. 证明很简单,如果它们不在同一强连通分量内,那么其中必然有两点x,y使得x→y的路径不存在,与题目要求矛盾. 我们考虑求出该图的所有强连通分量,然后对于每个强连通分量,检验从其中任一点

POJ 2186 -- Popular Cows【强连通分支 &amp;&amp; Tarjan缩点】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27198   Accepted: 10963 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 &

poj Popular Cows(tarjan +缩点)

Language: Default Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 24384   Accepted: 10007 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

POJ 2186 Popular Cows -- tarjan 缩点

链接: POJ 2186 Popular Cows 题意: 每一头牛都希望在牛群里面备受瞩目,在一个牛群中有N头牛(1<=N<=10000),你被给予M(1<=M<=50000)个关系对,形式如(A,B),这意味着A牛认为B牛比它更受欢迎,由于这种欢迎度是满足传递性的,那么若是A牛认为B牛更受欢迎,B牛认为C牛更受欢迎,那么A牛也会认为C牛更受欢迎.你的任务是计算出被所有牛受欢迎的牛的个数. 输入: 第一行两个整数 N 和 M 第2 到 M + 1 行,两个分开的数 A,B,意味着

强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)

poj 2186 Popular Cows 题意: 有N头牛, 给出M对关系, 如(1,2)代表1欢迎2, 关系是单向的且可以传递, 即1欢迎2不代表2欢迎1, 但是如果2也欢迎3那么1也欢迎3. 求被所有牛都欢迎的牛的数量. 限制: 1 <= N <= 10000 1 <= M <= 50000 思路: Kosaraju算法, 看缩点后拓扑序的终点有多少头牛, 且要判断是不是所有强连通分量都连向它. Kosaraju算法,分拆完连通分量后,也完成了拓扑序. /*poj 2186

POJ 2186 Popular Cows(Targin缩点)

传送门 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31808   Accepted: 12921 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 <=

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

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 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 &l