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. HDU 4622 求解区间字符串中的不同子串的个数

    题目大意: 给定一个长度<2000的串,再给最多可达10000的询问区间,求解区间字符串中的不同子串的个数 这里先考虑求解一整个字符串的所有不同子串的方法 对于后缀自动机来说,我们动态往里添加一 ...

  2. Section 1.4 Packing Rectangles

    本来是USACO Training的1.4.1的,但是介于今早过了食物链想起了这道题实在是太怨念了,翻出自己写的AC程序居然有5KB!! 思路很简单,枚举,而且就图中的六种情况.但是第六种变化状况太多 ...

  3. 组合——Program B

    CodeForces 478B Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u De ...

  4. 多线程同步内功心法——PV操作上(未完待续。。。)

    阅读本篇之前推荐阅读以下姊妹篇: <秒杀多线程第四篇一个经典的多线程同步问题> <秒杀多线程第五篇经典线程同步关键段CS> <秒杀多线程第六篇经典线程同步事件Event& ...

  5. 极客DIY:如何构建一台属于自己的基站

    写在前面(原文作者) 上周我去特拉维夫(Tel Aviv)探望我的朋友结果有了一些收获,一块崭新的BladeRF(x40),即一个支持USB3.0的SDR平台,这就意味着可以同时发送和接收信息了.而H ...

  6. loadrunner录制时弹出invalid application path!please check if application exists对话框

    问题:oadrunner录制时弹出invalid application path!please check if application exists对话框 原因:IE浏览器地址不对,需要手动重新选 ...

  7. How to Write Doc Comments for the Javadoc Tool

    http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html This document describe ...

  8. 删除目录下所有gif的图片

    find  -name "*.gif" -exec rm -fv {} \;

  9. R——启程——豆瓣影评分析

    专业统计的我,自然免不了学R的,今天仔细看了这篇教程(感谢学姐的推荐@喜欢算法的女青年),就学着用R仿照着做一个,作为R语言学习的起点吧. 影评数据是用python爬的,之后会在python爬虫系列补 ...

  10. Divisors_组合数因子个数

    Description Your task in this problem is to determine the number of divisors of Cnk. Just for fun -- ...