poj2186--Popular Cows(强连通+缩点)

poj2186:题目链接

题目大意:有n头奶牛,m个关系,A B表示A奶牛认为B是备受关注的,这个关系具有继承性,比如:A B 和 B C那么A奶牛也会认为C是备受关注的,问有多少头奶牛是受到除自己以外所以人关注的

首先进行强连通,那么每个连通块中的点都是受到该连通块中其它点的关注的,进行缩点,原图变成一颗树,如果有且只有一个缩点以后的点的出度为0,那么这个点就是受到所有人关注的。记录下该点代表原图中的几个点,输出

不用考虑是否所有点在一个图中,因为如果不在一个图中,不会满足“有且只有一个缩点以后的点的出度为0”

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <stack>
using namespace std ;
struct node
{
    int u , v ;
    int next ;
} edge[51000] , tree[51000] ;
int head[11000] , h_tree[11000] , cnt ;
int dnf[11000] , low[11000] , time ;
int vis[11000] , in[11000] , belong[11000] , num ;
int sum[11000] ;
stack <int> sta ;
void init()
{
    memset(head,-1,sizeof(head)) ;
    cnt = time = num = 0 ;
    memset(dnf,0,sizeof(dnf)) ;
    memset(low,0,sizeof(low)) ;
    memset(vis,0,sizeof(vis)) ;
    memset(in,0,sizeof(in)) ;
    memset(belong,0,sizeof(belong)) ;
    memset(sum,0,sizeof(sum)) ;
    while( !sta.empty() ) sta.pop() ;
}
void add(int u,int v)
{
    edge[cnt].u = u ;
    edge[cnt].v = v ;
    edge[cnt].next = head[u] ;
    head[u] = cnt++ ;
}
void add_tree(int u,int v)
{
    tree[cnt].u = u ;
    tree[cnt].v = v ;
    tree[cnt].next = h_tree[u] ;
    h_tree[u] = cnt++ ;
}
void tarjan(int u)
{
    dnf[u] = low[u] = ++time ;
    sta.push(u) ;
    vis[u] = 1 ;
    int i , v , j ;
    for(i = head[u] ; i != -1 ; i = edge[i].next)
    {
        v = edge[i].v ;
        if( !dnf[v] )
        {
            tarjan(v) ;
            low[u] = min(low[u],low[v]) ;
        }
        else if( vis[v] )
        {
            low[u] = min(low[u],dnf[v]) ;
        }
    }
    if( low[u] == dnf[u] )
    {
        ++num ;
        while( 1 )
        {
            j = sta.top() ;
            sta.pop() ;
            vis[j] = 0 ;
            belong[j] = num ;
            sum[num]++ ;
            if( j == u ) break ;
        }
    }
}
int main()
{
    int n , m , ans ;
    int u , v , i , j ;
    while( scanf("%d %d", &n, &m) != EOF )
    {
        init() ;
        ans = 0 ;
        while( m-- )
        {
            scanf("%d %d", &u, &v) ;
            add(u,v) ;
        }
        for(i = 1 ; i <= n ; i++)
            if( !dnf[i] ) tarjan(i) ;
        memset(in,0,sizeof(in)) ;
        for(i = 1 ; i <= n ; i++)
        {
            for(j = head[i] ; j != -1 ; j = edge[j].next)
            {
                u = belong[ edge[j].u ] ;
                v = belong[ edge[j].v ] ;
                if( u != v )
                    in[u]++ ;
            }
        }
        for(i = 1 ; i <= num ; i++)
            if( in[i] == 0 )
            {
                ans += sum[i] ;
                sum[0]++ ;
            }
        if( sum[0] == 1 )
            printf("%d\n", ans) ;
        else
            printf("0\n") ;
    }
    return 0 ;
}
时间: 2024-08-01 07:30:03

poj2186--Popular Cows(强连通+缩点)的相关文章

poj2186 Popular Cows --- 强连通

给一个有向图,问有多少结点是其他所有结点都可以到达的. 等价于,在一个有向无环图上,找出度为0 的结点,如果出度为0的结点只有一个,那么这个就是答案,如果大于1个,则答案是0. 这题有环,所以先缩点.求唯一出度为0的强连通分量. #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<iostream> #define inf 0x3f3f3f3f

POJ2186 Popular Cows [tarjan 缩点]

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31241   Accepted: 12691 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 强连通缩点

[题意]:给出一群牛中,一头牛认为另一头牛受欢迎的m对关系,关系式可以传递的,即若a认为b受欢迎,b认为c受欢迎,那么a也认为c受欢迎.求最多有多少头牛被所有的牛认为受欢迎. [思路]:把这些关系形成的强连通图缩成点,就形成了一有向无环图,这个图里的出度为0的点(有且只有一个)就是被所有牛认为受欢迎的点,说明若这个点原来是强连通图就要求出这个强连通图里的总点数, 1 #include<iostream> 2 #include<stdio.h> 3 #include<strin

强连通分量tarjan缩点——POJ2186 Popular Cows

这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定意味着v可达u.    相互可达则属于同一个强连通分量    (Strongly Connected Component, SCC) §有向图和它的转置的强连通分量相同 §所有SCC构成一个DAG(有向无环图) dfn[u]为节点u搜索的次序编号(时间戳),即首次访问u的时间 low[u]为u或u的

POJ2186 Popular Cows 【强连通分量Kosaraju】

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

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 --强连通分量

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

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

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

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 &