Popular Cows
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 30999   Accepted: 12580

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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define inf 0x3f3f3f3f
#define mod 10000
typedef long long ll;
using namespace std;
const int N=;
const int M=;
struct Node
{
int to,next;
}edge1[N*],edge2[N*];
//edge1用来存原图G,edge2用来存GT,即逆图
//都是用邻接表来储存的图,
int head1[N];//原图的邻接表的头结点
int head2[N];//逆图的邻接表的头结点
int mark1[N],mark2[N];
int tot1,tot2;
int cnt1,cnt2,st[N],belong[N];
int num,setNum[N];
struct Edge
{
int l,r;
}e[N*];//储存边 void add(int a,int b)//添加边a->b,在原图和逆图都需要添加
{
edge1[tot1].to=b;edge1[tot1].next=head1[a];head1[a]=tot1++;//邻接表存的原图
edge2[tot2].to=a;edge2[tot2].next=head2[b];head2[b]=tot2++;//邻接表存的逆图
}
void DFS1(int x)//深度搜索原图
{
mark1[x]=;
for(int i=head1[x];i!=-;i=edge1[i].next)
if(!mark1[edge1[i].to]) DFS1(edge1[i].to);
st[cnt1++]=x;//st数组是按照完成时间从小到大排序的
}
void DFS2(int x)//深度搜索逆图
{
mark2[x]=;
num++;
belong[x]=cnt2;
for(int i=head2[x];i!=-;i=edge2[i].next)
if(!mark2[edge2[i].to]) DFS2(edge2[i].to);
}
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
tot1=tot2=;
for(int i=;i<=n;i++)//初始化
{
head1[i]=head2[i]=-;
mark1[i]=mark2[i]=;
}
for(int i=;i<=m;i++)
{
int w,v;
scanf("%d%d",&w,&v);
e[i].l=w;e[i].r=v;//储存边
add(w,v);//建立邻接表
}
cnt1=cnt2=;
for(int i=;i<=n;i++)
{
if(!mark1[i])DFS1(i);
}
for(int i=cnt1-;i>=;i--)
{
if(!mark2[st[i]])
{
num=;
DFS2(st[i]);
setNum[cnt2++]=num;
}
}
int de[N];//计算出度
memset(de,,sizeof(de));
for(int i=;i<=m;i++)//计算各个DAG图的出度
{
if(belong[e[i].l]!=belong[e[i].r])//原图的边不属于同一连通分支
de[belong[e[i].l]]++;
} //计算DAG出度为0的个数
int cnt=,res;
for(int i=;i<cnt2;i++)
if(!de[i]){cnt++;res=i;}
if(cnt>) printf("0\n");
else printf("%d\n",setNum[res]);
}
return ;
}

kosaraju

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define inf 0x3f3f3f3f
#define mod 10000
typedef long long ll;
using namespace std;
const int N=;
const int M=;
int n,m,cnt,tim,top,cut;
int head[N],dfn[N],low[N],stack1[N];
int num[N],du[N],vis[N];
struct man {
int to,next;
} edg[M];
void init() {
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(head,-,sizeof(head));
memset(vis,,sizeof(vis));
memset(num,,sizeof(num));
memset(du,,sizeof(du));
cnt=;
tim=;
top=;
cut=;
}
void add(int u,int v) {
edg[cnt].to=v;
edg[cnt].next=head[u];
head[u]=cnt;
cnt++;
}
void dfs(int u,int fa) {
dfn[u]=tim;
low[u]=tim++;
vis[u]=;
stack1[top++]=u;
for(int i=head[u]; i!=-; i=edg[i].next) {
int v=edg[i].to;
if(!vis[v]) {
dfs(v,u);
low[u]=min(low[u],low[v]);
} else low[u]=min(low[u],dfn[v]);
}
if(low[u]==dfn[u]) {
cut++;
while(top>&&stack1[top]!=u) {
top--;
vis[stack1[top]]=;
num[stack1[top]]=cut;
}
}
}
int main() {
int u,v;
while(~scanf("%d%d",&n,&m)) {
init();
for(int i=; i<m; i++) {
scanf("%d%d",&u,&v);
add(u,v);
}
for(int i=; i<=n; i++) {
if(!vis[i])dfs(i,);
}
for(int i=; i<=n; i++) {
for(int j=head[i]; j!=-; j=edg[j].next) {
if(num[i]!=num[edg[j].to])du[num[i]]++;
}
}
int sum=,x;
for(int i=; i<=cut; i++) {
if(!du[i])sum++,x=i;
}
if(sum==) {
sum=;
for(int i=; i<=n; i++) {
if(num[i]==x)sum++;
}
cout<<sum<<endl;
} else puts("");
}
return ;
}

POJ 2186 Popular Cows(强连通)的更多相关文章

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

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

  2. POJ 2186 Popular Cows(强连通分量缩点)

    题目链接:http://poj.org/problem?id=2186 题目意思大概是:给定N(N<=10000)个点和M(M<=50000)条有向边,求有多少个“受欢迎的点”.所谓的“受 ...

  3. POJ 2186 Popular Cows --强连通分量

    题意:给定一个有向图,问有多少个点由任意顶点出发都能达到. 分析:首先,在一个有向无环图中,能被所有点达到点,出度一定是0. 先求出所有的强连通分支,然后把每个强连通分支收缩成一个点,重新建图,这样, ...

  4. POJ 2186 Popular Cows 强连通分量模板

    题意 强连通分量,找独立的块 强连通分量裸题 #include <cstdio> #include <cstdlib> #include <cstring> #in ...

  5. 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)

    poj 2186 Popular Cows 题意: 有N头牛, 给出M对关系, 如(1,2)代表1欢迎2, 关系是单向的且能够传递, 即1欢迎2不代表2欢迎1, 可是假设2也欢迎3那么1也欢迎3. 求 ...

  6. poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】

    题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Sub ...

  7. POJ 2186 Popular Cows (强联通)

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

  8. tarjan缩点练习 洛谷P3387 【模板】缩点+poj 2186 Popular Cows

    缩点练习 洛谷 P3387 [模板]缩点 缩点 解题思路: 都说是模板了...先缩点把有环图转换成DAG 然后拓扑排序即可 #include <bits/stdc++.h> using n ...

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

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

随机推荐

  1. High Performance Django

    构建高性能Django站点   性能 可用 伸缩 扩展 安全 build 1.审慎引入第三方库(是否活跃.是否带入query.是否容易缓存) 2.db:减少query次数 减少耗时query 减小返回 ...

  2. ssm开发的一点小技巧

    一般使用反转工作生成基础bean如Items然后我们使用的实体类一般是基础bean的拓展类ItemsCustomer,继承自基础类,这个是为了方便对于表字段的更改生成的bean影响减低我们查询一般是使 ...

  3. 转:gartner 2014-07 ETL工具象限排名

    ref:  http://www.gartner.com/technology/reprints.do?id=1-1YAXV15&ct=140728&st=sb

  4. UVALive 4682 XOR Sum (trie)

    题意:求一段连续的数字使得它们的异或和最大. 思路:首先利用前缀和求sum[i],这样求某段连续数字异或和最大就是求某两个j和i满足sum[i]^sum[j-1]最大,问题就变成了找两个数的异或最大. ...

  5. ios上架

    1.登录developer.apple.com 2.点击member center后 进下图 3.点击certificates Identifiers进下图 4.点击Certificates进下图,首 ...

  6. iOS开发之拖动图片

    步骤:1.首先创建一个single view application 2.然后添加一个新的cocoa touch class的类 3.添加的类遵守<UIGestureRecognizerDele ...

  7. C++面向过程解决三阶行列式问题

    #include<iostream> #include <cstdlib> using namespace std; int print() { cout<<&qu ...

  8. BZOJ1576 (最短路+并查集)

    #include <cstdio> #include <cstring> #include <algorithm> #include <queue> # ...

  9. Asp.net操作Excel----NPOI!!!!1

    前言 Asp.net操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,使 用NPOI能够帮助开发者在没有安装微软Office的情况下读写Off ...

  10. 数据库基本----SQL语句大全

    学会数据库是很实用D~~记录一些常用的sql语句...有入门有提高有见都没见过的...好全...收藏下...其实一般用的就是查询,插入,删除等语句而已....但学学存储过程是好事...以后数据方面的东 ...