Time Limit: 2000MS   Memory Limit: 65536K
     

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

  1. 3 3
  2. 1 2
  3. 2 1
  4. 2 3

Sample Output

  1. 1

Hint

Cow 3 is the only cow of high popularity.

Source

USACO 2003 Fall



题意:每一个奶牛都想成为牧群中最受仰慕的奶牛,在牧群中有n头奶牛,给定m对关系(A,B),表示A奶牛仰慕B奶牛。计算牧群中被其他奶牛仰慕的奶牛的数目。



思路:将n头奶牛的m个关系将会构建一个有向图,在图中强连通分量中的任意奶牛一定是被分量中的其他奶牛仰慕。所以问题就转化为在图中将强连通分量进行缩点,在形成的新图中,如果一个强连通分量集合的出度为零,说明这个集合被其他集合仰慕,而不仰慕其他的集合,所以如果在新图中集合出度为零的数目不大于1,则为出度为零集合中奶牛的数目,如果大于1,则出度为零集合之间没有仰慕关系的,所以结果为0.



  1. #include <cstdio>
  2. #include <cstring>
  3. #include <cstdlib>
  4. #include <cmath>
  5. #include <queue>
  6. #include <stack>
  7. #include <vector>
  8. #include <algorithm>
  9.  
  10. using namespace std;
  11.  
  12. const int Max = 10100;
  13.  
  14. typedef struct node
  15. {
  16. int v;
  17.  
  18. int next;
  19.  
  20. }Line;
  21.  
  22. vector<int>G[Max];
  23.  
  24. Line Li[Max*5];
  25.  
  26. int Head[Max],top;
  27.  
  28. int dfn[Max],low[Max],pre[Max];
  29.  
  30. int num[Max],Num,Du[Max];
  31.  
  32. int dep;
  33.  
  34. bool vis[Max];
  35.  
  36. int ans;
  37.  
  38. stack<int>S;
  39.  
  40. void AddEdge(int u,int v)
  41. {
  42. Li[top].v=v ; Li[top].next=Head[u];
  43.  
  44. Head[u]=top++;
  45. }
  46.  
  47. void Tarjan(int u)// Tarjan求强连通分量
  48. {
  49. dfn[u]=low[u]=dep++;
  50.  
  51. S.push(u);
  52.  
  53. for(int i=Head[u];i!=-1;i=Li[i].next)
  54. {
  55. if(dfn[Li[i].v]==-1)
  56. {
  57. Tarjan(Li[i].v);
  58.  
  59. low[u]=min(low[u],low[Li[i].v]);
  60. }
  61. else
  62. {
  63. low[u]=min(low[u],dfn[Li[i].v]);
  64. }
  65. }
  66.  
  67. if(low[u]==dfn[u])//强连通分量的根节点
  68. {
  69.  
  70. while(!S.empty())
  71. {
  72. int v = S.top();
  73.  
  74. S.pop();
  75.  
  76. pre[v] = Num;//给分量集合标号
  77.  
  78. G[Num].push_back(v);//记录集合对应的点
  79.  
  80. num[Num]++;
  81.  
  82. if(v==u)
  83. {
  84. break;
  85. }
  86. }
  87.  
  88. Num++;
  89. }
  90.  
  91. }
  92.  
  93. int main()
  94. {
  95.  
  96. int n,m;
  97.  
  98. while(~scanf("%d %d",&n,&m))
  99. {
  100. top = 0;
  101.  
  102. memset(Head,-1,sizeof(Head));
  103.  
  104. int u,v;
  105.  
  106. for(int i=0;i<m;i++)
  107. {
  108. scanf("%d %d",&u,&v);
  109.  
  110. AddEdge(u,v);
  111. }
  112.  
  113. memset(dfn,-1,sizeof(dfn));
  114.  
  115. memset(num,0,sizeof(num));
  116.  
  117. for(int i =0;i<=n;i++)
  118. {
  119. G[i].clear();
  120. }
  121.  
  122. dep = 0;Num = 0;
  123.  
  124. for(int i=1;i<=n;i++)
  125. {
  126. if(dfn[i]==-1)
  127. {
  128. Tarjan(i);
  129. }
  130. }
  131.  
  132. memset(Du,0,sizeof(Du));
  133.  
  134. for(int i=0; i<Num ;i++) //判断强连通分量的出度
  135. {
  136. memset(vis,false,sizeof(vis));
  137.  
  138. for(int k=0;k<G[i].size();k++)
  139. {
  140. for(int j=Head[G[i][k]]; j!=-1;j=Li[j].next)
  141. {
  142. if(i!=pre[Li[j].v])
  143. {
  144. if(!vis[pre[Li[i].v]])//由于不同的强连通分量之间相连的边可能不止一条,所以要判断是不是已经统计过。
  145. {
  146. vis[pre[Li[i].v]]=true;
  147.  
  148. Du[i]++;
  149. }
  150. }
  151. }
  152. }
  153. }
  154.  
  155. ans = 0;
  156.  
  157. int ant = 0;
  158.  
  159. for(int i=0;i<Num;i++)//如果超过一个的出度为零的强连通分量,则这些连通分量就不能被其他的牛都仰慕。
  160. {
  161. if(Du[i]==0)
  162. {
  163. ans+=num[i];
  164.  
  165. ant++;
  166.  
  167. }
  168. }
  169.  
  170. printf("%d\n",ant<=1?ans:0);
  171.  
  172. }
  173.  
  174. return 0;
  175. }

Popular Cows-POJ2186Tarjan的更多相关文章

  1. POJ 2186 Popular Cows(Targin缩点)

    传送门 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31808   Accepted: 1292 ...

  2. POJ2186 Popular Cows [强连通分量|缩点]

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31241   Accepted: 12691 De ...

  3. poj 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 29908   Accepted: 12131 De ...

  4. [强连通分量] POJ 2186 Popular Cows

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 31815   Accepted: 12927 De ...

  5. POJ 2186 Popular Cows(强连通)

                                                                  Popular Cows Time Limit: 2000MS   Memo ...

  6. poj 2186 Popular Cows (强连通分量+缩点)

    http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissi ...

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

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 27698   Accepted: 11148 De ...

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

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 Des ...

  9. POJ 2186 Popular Cows (强联通)

    id=2186">http://poj.org/problem? id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 655 ...

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

    这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定 ...

随机推荐

  1. ThinPHP基础

    注:约定([书写]规则)胜于配置 *测试连接是否成功:localhost/tp/index.php1.localhost/tp/index.php(入口文件)/Home(模块名)/Index(控制器名 ...

  2. 用Arduino剖析PWM脉宽调制

    PWM(Pulse Width Modulation)简介 PWM,也就是脉冲宽度调制,用于将一段信号编码为脉冲信号,也就是方波信号.多用于在数字电路中驱动负载随时间变化的电子元件,如LED,电机等. ...

  3. scala中的数组的转换操作

    1.共有两种操作 转换成一种新的数组 2.yield转换 3.函数式编程转换

  4. iOS 因为reason: 'Pushing the same view controller instance more than once is not supported而奔溃(下)

    这个问题是什么意思呢,之前遇到过几次,但程序再次打开时没有问题,也就没有重视,今天又遇到了,无法忍受啊. 控制台报的错误是:"不支持多次推入相同的视图控制器实例". 什么原因造成的 ...

  5. QMap

    #include <QCoreApplication> #include<QMap> #include<QDebug> int main(int argc, cha ...

  6. 异或密码---hdu5968(CCPC合肥,二分)

     题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5968 思路:先把所有的连续异或值保存起来,排序,然后用二分找到距离x最近的那个点,判断即可:   # ...

  7. 【vue.js权威指南】读书笔记(第一章)

    最近在读新书<vue.js权威指南>,一边读,一边把笔记整理下来,方便自己以后温故知新,也希望能把自己的读书心得分享给大家. [第1章:遇见vue.js] vue.js是什么? vue.j ...

  8. centos 安装redis并加入系统服务

    1.安装redis wget http://download.redis.io/releases/redis-3.2.5.tar.gz 解压:tar -zxvf redis-3.2.5.tar.gz ...

  9. Hibernate原理解析-Hibernate中实体的状态

  10. C# 实现函数回调

    public class Lib { public delegate void UserFunctionCB(); private static UserFunctionCB m_userFnCB; ...