1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4776  Solved: 2542

Description

  每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这
种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头
牛被所有的牛认为是受欢迎的。

Input

  第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可
能出现多个A,B)

Output

  一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3
1 2
2 1
2 3

Sample Output

1

HINT

100%的数据N<=10000,M<=50000
/*这是一个缩点Tarjan求环的裸题 */
#include<iostream>
#include <cstdio>
#include <cstring>
using namespace std; const int Maxn = ;
const int Maxm = ;
struct node
{
int to,next;
} edge[Maxm];
int n,m,head[Maxn],dfn[Maxn],low[Maxn],stack1[Maxn],num[Maxn],du[Maxn],vis[Maxn],cnt,tt,top,cut; 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));
} void addedge(int u,int v)
{
edge[cnt].to=v;
edge[cnt].next=head[u];
head[u]=cnt;
cnt++;
} void Tarjan(int u,int fa)
{
dfn[u]=tt;
low[u]=tt;
tt++;
vis[u]=;
stack1[top]=u;
top++;
for(int i=head[u]; i!=-; i=edge[i].next)
{
int v=edge[i].to;
if(!vis[v])
{
Tarjan(v,u);
low[u]=min(low[u],low[v]);
}
else if(vis[v])
{
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)!=EOF)
{
init();
for(int i=; i<m; i++)
{
scanf("%d%d",&u,&v);
addedge(u,v);
}
for(int i=; i<=n; i++)
{
if(!vis[i])
{
Tarjan(i,);
}
}
for(int i=; i<=n; i++)
{
for(int j=head[i]; j!=-; j=edge[j].next)
{
if(num[i]!=num[edge[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++;
}
}
printf("%d\n",sum);
}
}
return ;
}

心若向阳,无谓悲伤

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int N=,M=;
int n=,m=;
int head[N],to[M],next[M],edge=;
int dfn[N],inS[N],idx=,low[N];
int stk[N],top=;
int comp[N],n2=,cnt[N];
int in[N];
int head2[N],to2[M],next2[M],edge2=;
int q[N*],front=,back=,vis[N];
inline void addEdge(int u,int v) {
to[edge]=v,next[edge]=head[u],head[u]=edge++;
}
void tarjan(int x) {
dfn[x]=low[x]=idx++;
stk[top++]=x;
inS[x]=;
for (int e=head[x];~e;e=next[e]) {
int& v=to[e];
if (!dfn[v]) {
tarjan(v);
low[x]=min(low[x],low[v]);
} else if (inS[x])
low[x]=min(low[x],dfn[v]);
}
if (dfn[x]==low[x]) {
++n2;
int u=;
do {
u=stk[--top];
comp[u]=n2;
inS[u]=;
++cnt[n2];
} while (u!=x);
}
}
inline void addEdge2(int u,int v) {
++in[v];
to2[edge2]=v,next2[edge2]=head2[u],head2[u]=edge2++;
}
inline void build() {
for (int i=;i<=n;++i)
for (int e=head[i];~e;e=next[e]) {
int &u=comp[i],&v=comp[to[e]];
if (u!=v)
addEdge2(v,u);
}
}
inline int bfs(int s) {
front=back=;
memset(vis,,sizeof(vis));
q[back++]=s;
vis[s]=;
while (front<back) {
int x=q[front++];
for (int e=head2[x];~e;e=next2[e]) {
int& v=to2[e];
if (!vis[v]) {
q[back++]=v;
vis[v]=;
}
}
}
for (int i=;i<=n2;++i)
if (!vis[i])
return ;
return ;
}
int main(void) {
memset(head,-,sizeof(head));
scanf("%d %d",&n,&m);
while (m--) {
int u=,v=;
scanf("%d %d",&u,&v);
addEdge(u,v);
}
for (int i=;i<=n;++i)
if (!dfn[i])
tarjan(i);
//建缩点以后的反图 就所有入度为0的点bfs
memset(head2,-,sizeof(head2));
build();
int ans=;
for (int i=;i<=n2;++i)
if (!in[i])
if (bfs(i))
ans+=cnt[i];
printf("%d\n",ans);
return ;
}

上个代码在洛谷不过,求大神指点

bzoj1051受欢迎的牛(Tarjan)的更多相关文章

  1. 【bzoj1051】 [HAOI2006]受欢迎的牛 tarjan缩点判出度算点数

    [bzoj1051] [HAOI2006]受欢迎的牛 2014年1月8日7450 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B ...

  2. 【BZOJ1051】1051: [HAOI2006]受欢迎的牛 tarjan求强连通分量+缩点

    Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认 ...

  3. BZOJ1051:受欢迎的牛(并查集 / Tarjan)

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 8161  Solved: 4460 Description ...

  4. [BZOJ1051][HAOI2006] 受欢迎的牛 tarjan求联通分量

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 5687  Solved: 3016[Submit][Sta ...

  5. bzoj 1051: [HAOI2006]受欢迎的牛 tarjan缩点

    1051: [HAOI2006]受欢迎的牛 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2092  Solved: 1096[Submit][Sta ...

  6. BZOJ 1051: [HAOI2006]受欢迎的牛( tarjan )

    tarjan缩点后, 有且仅有一个出度为0的强连通分量即answer, 否则无解 ----------------------------------------------------------- ...

  7. p2341&bzoj1051 受欢迎的牛

    传送门(洛谷) 传送门(bzoj) 题目 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎. 这 种关系是具有传递性的,如果A认为B受欢迎,B认为C ...

  8. B1051 受欢迎的牛 tarjan缩点

    就是一道tarjan缩点的板子,之前在洛谷做过.但是我发现一个事,就是函数里面有一句话: void tarjan(int x) { dfn[x] = low[x] = ++tot; str[++top ...

  9. BZOJ1051 受欢迎的牛

    http://www.lydsy.com/JudgeOnline/problem.php?id=1051 Description 每一头牛的愿望就是变成一头最受欢迎的牛.现在有N头牛,给你M对整数(A ...

随机推荐

  1. python之更加抽象 2014-4-6

    #更加抽象 12:50pm- 14:50 p112- 1.对象的魔力 多态 如count 在多种数据类型中都可以实现计数的功能 封装 对全局作用域中其他区域隐藏多余信息的原则 继承2.类和类型 创建类 ...

  2. Webdriver元素定位2(XPath)

    XPath即为XML路径语言,它是一种用来确定XML文档中某部分位置的语言.XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力. 绝对路径定位 案例:在百度首页搜索框输入selenium ...

  3. Leetcode 187.重复的DNA序列

    重复的DNA序列 所有 DNA 由一系列缩写为 A,C,G 和 T 的核苷酸组成,例如:"ACGAATTCCG".在研究 DNA 时,识别 DNA 中的重复序列有时会对研究非常有帮 ...

  4. Spring Boot Jpa 表名小写转大写

    今天在使用SpringBoot整合Hibernate后创建表,表名为小写,而在linux下,mysql的表名是区分大小写的,因此在我的数据表中,就出现了两个一样的表 act_id_user 和  AC ...

  5. Memory Ordering in Modern Microprocessors

    Linux has supported a large number of SMP systems based on a variety of CPUs since the 2.0 kernel. L ...

  6. 新vim配置文件

    "******************************************************特殊设置************************************ ...

  7. hdu_1028_Ignatius and the Princess III

    Ignatius and the Princess III Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K ...

  8. node+mongodb+win7

    一.安装mongodb,参照教程,注意要先启动mongod.exe,再启动mongd.exe.

  9. Restful 级别划分以及HATEOAS是什么?

    Restful简介 Rest是一种软件架构风格.设计风格,而不是标准,只是提供了一组设计原则和约束条件.它主要用于客户端和服务器交互类的软件.基于这个风格设计的软件可以更简洁,更有层次,更易于实现缓存 ...

  10. mac idea快捷键(部分常用)

    shift+F6重命名 shift+enter 换到下一行 shift+F8等同eclipse的f8跳到下一个断点,也等同eclipse的F7跳出函数 F8等同eclipse的f6跳到下一步F7等同e ...