现在的位置: 首页 > 综合 > 正文

poj 2186 Popular Cows(korasaju)

2018年03月17日 ⁄ 综合 ⁄ 共 1291字 ⁄ 字号 评论关闭
题意:有N头牛 每一头牛都梦想着成为popular cow,(但这是不可能滴) 有m组仰慕的关系,仰慕有传递性
比如说A觉得B是popular and B thinks C is popular, then A thinks C is
popalur also;
现在问有多少头牛是会被其他牛都仰慕。

思路:求强连通分量,缩成点 点内的头当然是相互仰慕的咯!! 然后求新的图 的出度 出度也0的点就会被所有牛仰慕
算出出度为0的强连通分量里点的个数就OK了,注意 可能有多个出度为0的点,这时输出0(不满足要求) 刚学korasaju
算法,所以用它做 详解见上一篇

92MS

#include <stdio.h>
#include <string.h>
#define VM 10005
#define EM 50005

struct E
{
    int
to,next;
} edge1[EM],edge2[EM];
int head1[VM],head2[VM],p,n;
int scc_id[VM],vis[VM],order[VM],cnt,scc;
 int outdeg[VM],indeg[VM];
void addedge (int cu,int cv)
{
    edge1[p].to
= cv;
   
edge1[p].next = head1[cu];
    head1[cu] =
p;
    edge2[p].to
= cu;
   
edge2[p].next = head2[cv];
    head2[cv] =
p ++;
}

void dfs (int u)
{
    for (int i =
head1[u]; i != -1; i = edge1[i].next)
    {
       
int v = edge1[i].to;
       
if (!vis[v])
       
{
           
vis[v] = 1;
           
dfs(v);
       
}
    }
    order[++cnt]
= u;
}
void redfs (int u)
{
    for (int i =
head2[u]; i != -1; i = edge2[i].next)
    {
       
int v = edge2[i].to;
       
if (!scc_id[v])
       
{
           
scc_id[v] = scc;
           
redfs (v);
       
}
    }
}
void korasaju ()
{
    int
u,i;
    cnt = scc =
0;
    memset
(vis,0,sizeof(vis));
    memset
(scc_id,0,sizeof(scc_id));
    memset
(order,0,sizeof(order));
    for (u = 1;
u <= n; u ++)
       
if (!vis[u])
       
{
           
vis[u] = 1;
           
dfs(u);
       
}
    for (i = n;
i > 0; i --)
    {
       
u = order[i];
       
if (!scc_id[u])
       
{
           
scc_id[u] = ++scc;
       

抱歉!评论已关闭.