POJ 2186 Popular Cows (强联通)

id=2186">http://poj.org/problem?

id=2186


Popular Cows

Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 23819   Accepted: 9767

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.

Source

field=source&key=USACO+2003+Fall" style="text-decoration:none">USACO 2003 Fall

题意:

一群牛中找被其它全部牛觉得是受欢迎的牛的数量。当中受欢迎有传递性。比方A觉得B受欢迎。B觉得C受欢迎,那么A觉得C也是受欢迎的。

分析:

假设某头牛是受欢迎的。那么从其它全部牛出发都能到达这头牛。假设用搜索做似乎太过复杂。首先进行强联通缩点。这样得到一个DAG,假设该DAG有且仅有一个出度为0的缩点点(极大强联通分量),那么这个缩点包含的牛的数量即为答案。

/*
 *
 * Author : fcbruce <[email protected]>
 *
 * Time : Tue 14 Oct 2014 03:00:16 PM CST
 *
 */
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cstdlib>
#include <algorithm>
#include <ctime>
#include <cctype>
#include <cmath>
#include <string>
#include <cstring>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>
#define sqr(x) ((x)*(x))
#define LL long long
#define itn int
#define INF 0x3f3f3f3f
#define PI 3.1415926535897932384626
#define eps 1e-10

#ifdef _WIN32
  #define lld "%I64d"
#else
  #define lld "%lld"
#endif

#define maxm 50007
#define maxn 10007

using namespace std;

int n,m;
int fir[maxn];
int u[maxm],v[maxm],nex[maxm];
int e_max;

int pre[maxn],low[maxn],sccno[maxn],w[maxn];
int st[maxn],top;
int scc_cnt,dfs_clock;

int deg[maxn];

inline void add_edge(int s,int t)
{
  int e=e_max++;
  u[e]=s;v[e]=t;
  nex[e]=fir[u[e]];fir[u[e]]=e;
}

void tarjan_dfs(int s)
{
  pre[s]=low[s]=++dfs_clock;
  st[++top]=s;
  for (int e=fir[s];~e;e=nex[e])
  {
    int t=v[e];
    if (pre[t]==0)
    {
      tarjan_dfs(t);
      low[s]=min(low[s],low[t]);
    }
    else
    {
      if (sccno[t]==0)
        low[s]=min(low[s],pre[t]);
    }
  }

  if (pre[s]==low[s])
  {
    scc_cnt++;
    for (;;)
    {
      int x=st[top--];
      sccno[x]=scc_cnt;
      w[scc_cnt]++;
      if (x==s) break;
    }
  }
}

void find_scc()
{
  top=-1;
  scc_cnt=dfs_clock=0;
  memset(pre,0,sizeof pre);
  memset(low,0,sizeof low);
  memset(w,0,sizeof w);
  for (int i=1;i<=n;i++)
    if (pre[i]==0) tarjan_dfs(i);
}

int main()
{
#ifdef FCBRUCE
  freopen("/home/fcbruce/code/t","r",stdin);
#endif // FCBRUCE

  scanf("%d%d",&n,&m);

  e_max=0;
  memset(fir,-1,sizeof fir);

  for (int e=0,u,v;e<m;e++)
  {
    scanf("%d%d",&u,&v);
    add_edge(u,v);
  }

  find_scc();

  memset(deg,0,sizeof deg);

  for (int e=0;e<e_max;e++)
  {
    if (sccno[u[e]]==sccno[v[e]]) continue;
    deg[sccno[u[e]]]++;
  }

  int cnt=0,the_one;

  for (int i=1;i<=scc_cnt;i++)
  {
    if (deg[i]==0)
    {
      cnt++;
      the_one=i;
    }
  }

  if (cnt==1) printf("%d\n",w[the_one]);
  else  puts("0");

  return 0;
}
时间: 2024-10-11 04:54:40

POJ 2186 Popular Cows (强联通)的相关文章

POJ 2186 Popular Cows (强联通分量)

链接 :http://poj.org/problem?id=2186 一个联通分量里的所有的牛满足任何一个被其他牛认为是红人.强联通缩点之后 只需要找到一个且只有一个联通分量且它的出度为0 答案就是这个强联通分量点的个数. #include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stac

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

题意:给定一个有向图,问有多少个点由任意顶点出发都能达到. 分析:首先,在一个有向无环图中,能被所有点达到点,出度一定是0. 先求出所有的强连通分支,然后把每个强连通分支收缩成一个点,重新建图,这样,这个有向图就变成了一个有向无环图. 在这个新的图中,只需知道出度为0的点有几个即可. 如果出度为0的点超过1个,则输出0:否则输出出度为0的点所代表的那个强连通分支的分量数即可. 用Tarjan求强连通分量 代码: #include <iostream> #include <cstdio&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).你的任务是计算牧群中受每头奶牛仰慕的奶牛数量. 思路:首先可以知道,在同一个强连通分量内的点一定互

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很受欢迎,问根据给出的关系,有多少头牛被其他所有的牛都认为是受欢迎的? 解题思路: 对于一个有向无环图来说,其中有且仅有一个点出度为零,那么这个特殊的点,可以由其他任何点到达.那么接下来我们直接对所给的图进行强连通分量划分,然后把每个强连通分量看做一个点,判定出度为零的点有几个,如果有一个就输出这个点对应的强连通分量含有的节点个数,否则为零

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

POJ 2186 Popular cows(Kosaraju+强联通分量模板)

题目链接:http://poj.org/problem?id=2186 题目大意:给定N头牛和M个有序对(A,B),(A,B)表示A牛认为B牛是红人,该关系具有传递性,如果牛A认为牛B是红人,牛B认为牛C是红人,那么牛A也认为牛C是红人.求被其他所有牛认为是红牛的牛的总数. 解题思路:把所有牛看成顶点,把有序对(A,B)看成从A到B的有向边,那么题目就变成了求所有顶点都可到达的顶点的总数.我们可以得到一个结论,如果一个强连通分量里有一头牛被认为是红人,那么该强联通分量里的所有牛都是红人,这显然是