POJ 2186 -- Popular Cows【强连通分支 && 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 <= 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.

题意:每个奶牛有梦想成为牧群中最受奶牛仰慕的奶牛, 在牧群中, 有N头奶牛 给定M对有序对(A, B),表示A仰慕B。由于仰慕关系具有传递性,也就是说,如果A仰慕B,B仰慕C, 则A也仰慕C,计算牧群中受每头牛仰慕的奶牛数量

解析:

如果强连通分量中一头牛A受到强连通分量外另一头牛B的仰慕,则该强连通分量中的每一头牛都受到B的仰慕;

如果强连通分量中一头牛A仰慕强连通分量外的另一头牛B,则强连通分量中的每一头牛都仰慕B。

所以将【每个强连通分支】缩成一个点,记录每个【缩点】的出度,并构造新图。统计出度为0的【缩点】的个数,如果正好为1,则说明该【缩点】能被其他所有【缩点】走到。该【缩点】包含点的个数就是我们所求答案。

简化来说:

给出一个有向图,求一共有多少个点,满足这样的条件:所有其它的点都可以到达这个点。

强连通分支+缩点,然后统计每个【缩点】的出度,如果只有一个为0,则输出其内部点的个数,如果有多个为0,说明没有答案,输出0。

#include <cstdio>
#include <cstring>
#include <vector>
#include <queue>
#include <algorithm>
#define maxn 10000 + 1000
#define maxm 50000 + 5000
using namespace std;
int n, m;
struct node {
	int u, v, next;
};
node edge[maxm];
int head[maxn], cnt;
int low[maxn], dfn[maxn];
int dfs_clock;
int Stack[maxn];
bool Instack[maxn];
int top;
int Belong[maxn] , scc_clock;
int out[maxn];

void init(){
	cnt = 0;
	memset(head, -1, sizeof(head));
}

void addedge(int u, int v){
	edge[cnt] = {u, v, head[u]};
	head[u] = cnt++;
}

void getmap(){
    while(m--){
        int a, b;
        scanf("%d%d", &a, &b);
        addedge(a, b);
    }
}

void tarjan(int u, int per){
    int v;
    low[u] = dfn[u] = ++dfs_clock;
    Stack[top++] = u;
    Instack[u] = true;
    for(int i = head[u]; i != -1; i = edge[i].next){
        v = edge[i].v;
        if(!dfn[v]){
            tarjan(v, u);
            low[u] = min(low[v], low[u]);
        }
        else if(Instack[v]){
            low[u] = min(low[u], dfn[v]);
        }
    }
    if(dfn[u] == low[u]){
        scc_clock++;
        do{
            v = Stack[--top];
            Instack[v] = false;
            Belong[v] = scc_clock;
        }while(u != v);
    }
}

void find(){
    memset(low, 0, sizeof(low));
    memset(dfn, 0, sizeof(dfn));
    memset(Instack, false, sizeof(Instack));
    memset(Belong, 0, sizeof(Belong));
    dfs_clock = scc_clock = top = 0;
    for(int i = 1; i <= n; ++i){
        if(!dfn[i])
            tarjan(i, i);
    }
}

void suodian(){
    for(int i = 1; i <= scc_clock; ++i)
        out[i] = 0;
    for(int i = 0; i < cnt; ++i){
        int u = Belong[edge[i].u];
        int v = Belong[edge[i].v];
        if(u != v)
            out[u]++;
    }
}

void solve(){
	int ans = 0;
	int temp = 0;
	int i;
    for(int i = 1; i <= scc_clock; ++i){
        //printf("%d\n", out[i]);
        if(out[i] == 0){
        	temp = i;
        	ans++;
        	if(ans > 1){
        		printf("0\n");
        		return ;
			}
		}
    }
    int num = 0;
    for(int i = 1; i <= n; ++i){
    	if(Belong[i] == temp)
    		num++;
    }
    printf("%d\n", num);
}

int main (){
	while(scanf("%d%d", &n, &m) != EOF){
        init();
        getmap();
        find();
        suodian();
        solve();
	}
	return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-10 23:29:49

POJ 2186 -- Popular Cows【强连通分支 && Tarjan缩点】的相关文章

poj 2186 Popular Cows【tarjan求scc个数&amp;&amp;缩点】【求一个图中可以到达其余所有任意点的点的个数】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27698   Accepted: 11148 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 (tarjan)

Popular Cows 题目传送:Popular Cows 思路:tarjan算法求强连通分量 AC代码: #include <map> #include <set> #include <cmath> #include <deque> #include <queue> #include <stack> #include <cstdio> #include <cctype> #include <strin

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 <=

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,意味着

Poj 2186 Popular Cows (Tarjan)

题目链接: Poj 2186 Popular Cows 题目描述: 有n只牛,牛之间存在一些关系,比如a认为b很受欢迎,b认为c很受欢迎,这样呢,a也会认为c很受欢迎,问根据给出的关系,有多少头牛被其他所有的牛都认为是受欢迎的? 解题思路: 对于一个有向无环图来说,其中有且仅有一个点出度为零,那么这个特殊的点,可以由其他任何点到达.那么接下来我们直接对所给的图进行强连通分量划分,然后把每个强连通分量看做一个点,判定出度为零的点有几个,如果有一个就输出这个点对应的强连通分量含有的节点个数,否则为零

POJ 2186 Popular Cows --强连通分量

题意:给定一个有向图,问有多少个点由任意顶点出发都能达到. 分析:首先,在一个有向无环图中,能被所有点达到点,出度一定是0. 先求出所有的强连通分支,然后把每个强连通分支收缩成一个点,重新建图,这样,这个有向图就变成了一个有向无环图. 在这个新的图中,只需知道出度为0的点有几个即可. 如果出度为0的点超过1个,则输出0:否则输出出度为0的点所代表的那个强连通分支的分量数即可. 用Tarjan求强连通分量 代码: #include <iostream> #include <cstdio&g

poj 2186 Popular Cows 【强连通】

题目:poj 2186 Popular Cows 题意:n头牛,其中存在一些牛相互崇拜,具有传递性,问有多少头牛是被其他所有牛崇拜的. 分析:建立一个有向图,然后强连通缩点,之后求出度为0的点,假如存在多个,那么ans = 0,因为缩点之后如果x崇拜y,x也崇拜z,那么肯定y和z不能互相崇拜,不满足. 然后求出度为0的这个点缩点前环上有多少个点就ans AC代码: #include <cstdio> #include <vector> #include <iostream&g

POJ 2186 Popular Cows (强连通分量)

POJ 2186 Popular Cows 链接:http://poj.org/problem?id=2186 题意:每头奶牛都梦想着成为牧群中最受奶牛仰慕的奶牛.在牧群中,有N 头奶牛,1≤N≤10,000,给定M 对(1≤M≤50,000)有序对(A, B),表示A 仰慕B.由于仰慕关系具有传递性,也就是说,如果A 仰慕B,B 仰慕C,则A 也仰慕C,即使在给定的M 对关系中并没有(A, C).你的任务是计算牧群中受每头奶牛仰慕的奶牛数量. 思路:首先可以知道,在同一个强连通分量内的点一定互

强连通分量分解 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 【强连通分量Tarjan算法 + 树问题】

题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27496   Accepted: 11059 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