题目描述

每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶

牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜

欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你

算出有多少头奶牛可以当明星。

输入输出格式

输入格式:

 第一行:两个用空格分开的整数:N和M

 第二行到第M + 1行:每行两个用空格分开的整数:A和B,表示A喜欢B

输出格式:

 第一行:单独一个整数,表示明星奶牛的数量

输入输出样例

输入样例#1:

3 3
1 2
2 1
2 3
输出样例#1:

1

说明

只有 3 号奶牛可以做明星

【数据范围】

10%的数据N<=20, M<=50

30%的数据N<=1000,M<=20000

70%的数据N<=5000,M<=50000

100%的数据N<=10000,M<=50000

感想

2019年8月16日12:39:48:看自己博客学新算法

最近在纠结写博客那么详细会不会太浪费时间了,毕竟只是给自己或者周围人看的……但今天再次开始搞tarjan,发现自己就写了这一篇文章,还那么简略……以至于还要去其他博客学习……不过我看出来了,当时的代码里,b数组没必要,判断每一条边时使用e数组就好

2019年8月16日13:27:54 重新写了一遍,WA了,原因是tarjan函数里,把u点入栈以后忘记更新instack数组了。加上就A了(但出栈的时候还是忘记更新instack数组了,所以第二份代码是有锅的。不过也A了,这到底是没必要,还是数据水……留坑)。重写画了半个小时,好长啊,中途还磕磕绊绊,比如tarjan内部的几种判断的顺序啥的……

解题思路

  tarjan找到强连通分量,然后缩点,统计缩了之后每个强连通分量的出度,如果只有一个出度为零的强连通分量,答案就是这个强连通分量里点的个数;如果出度为零的强连通分量不止一个,那么答案就为0。

  记得Neil做这题的时候曾经疑惑过——如果缩点后得到的图还是成环咋办?那么所有强连通分量出度都不为零了,答案应该为0,但事实上应该所有奶牛都受欢迎了……原来这个算法正确性是这么保证的——tarjan算法有一个性质:求出的强连通分量一定是极大强连通分量,所以缩出来的点肯定不会成环。

源代码

2017年7月2日的

#include<cstdio>
#include<algorithm> int n,m; struct edge{
int u,v;
}b[]; struct Edge{
int nxt,to;
}e[];
int head[]={},cnt=;
void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
} int id[]={},index=;
int num[]={}; int dfn[]={},low[]={},dfs_time=;
int stack[]={},top=;
bool instack[]={};
void tarjan(int u)
{
low[u]=dfn[u]=++dfs_time;
stack[top++]=u;
instack[u]=;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])
tarjan(v),low[u]=std::min(low[v],low[u]);
else if(instack[v])
low[u]=std::min(low[v],low[u]);
}
if(dfn[u]==low[u])
{
index++;
int v;
do{
v=stack[--top];
stack[top]=;
id[v]=index,instack[v]=;
num[index]++;
}while(v!=u);
}
} int out[]={}; int main()
{
//freopen("cow.in","r",stdin);
//freopen("cow.out","w",stdout);
scanf("%d%d",&n,&m);
for(int i=,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
b[i]={u,v};
}
for(int i=;i<=n;i++)
if(!dfn[i])
tarjan(i);
for(int i=;i<=m;i++)
if(id[b[i].u]!=id[b[i].v])
out[id[b[i].u]]++; int ans=;
for(int i=;i<=index;i++)
if(!out[i])
{
if(ans)
{
printf("0\n");
return ;
}
else ans=num[i];
}
printf("%d\n",ans);
return ;
}

2019年8月16日13:39:02更新——

 #include<cstdio>
#include<algorithm> const int MAXN=1e4+,MAXM=5e4+; int n,m; struct Edge{
int nxt,to;
}e[MAXM];
int cnt=,head[MAXN];
inline void add(int u,int v)
{
e[cnt]={head[u],v};
head[u]=cnt++;
} int dfn[MAXN],low[MAXN],dfst=;//时间戳们
int stack[MAXN],top=;
bool instack[MAXN];
int id[MAXN],index=;//缩点用的新id
int num[MAXN];//统计每个强连通分量大小
int out[MAXN];//统计各强连通分量出度
void tarjan(int u)
{
dfn[u]=low[u]=dfst++;//打时间戳
stack[++top]=u;//入栈
instack[u]=;
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(!dfn[v])//树边
{
tarjan(v);
low[u]=std::min(low[u],low[v]);
}
else if(instack[v])//返祖边
{
low[u]=std::min(low[u],low[v]);//暂时先更新low,不急着出栈,以便找到极大强连通分量
}
}
if(low[u]==dfn[u])//得割点一个,出栈缩点
{
do//为啥都在栈里来着?
{
id[stack[top--]]=index;
num[index]++;//这句话可以放在外面O(1)处理
}while(stack[top+]!=u);
index++;
}
} int main()
{
scanf("%d%d",&n,&m);
for(int i=,u,v;i<=m;i++)
{
scanf("%d%d",&u,&v);
add(u,v);
}
for(int i=;i<=n;i++)
{
if(!dfn[i]) tarjan(i);
} for(int u=;u<=n;u++)//统计出度
{
for(int i=head[u];i;i=e[i].nxt)
{
int v=e[i].to;
if(id[u]!=id[v])
{
out[id[u]]++;
}
}
}
int ans=;
for(int i=;i<index;i++)
{
if(!out[i])
{
if(ans)
{
puts("");
return ;
}
ans=num[i];
}
}
printf("%d\n",ans);
return ;
}

洛谷 P2341 BZOJ 1051 [HAOI2006]受欢迎的牛的更多相关文章

  1. BZOJ 1051: [HAOI2006]受欢迎的牛 缩点

    1051: [HAOI2006]受欢迎的牛 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/ ...

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

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

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

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

  4. BZOJ 1051: [HAOI2006]受欢迎的牛(SCC)

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

  5. BZOJ 1051: [HAOI2006]受欢迎的牛

    Description 一个有向图,求所以能被别的点到达的点的个数. Sol Tarjan + 强连通分量 + 缩点. 缩点以后找强连通分量,缩点,然后当图有且仅有1个出度为1的点时,有答案. Cod ...

  6. BZOJ 1051: [HAOI2006]受欢迎的牛 强连通缩点

    题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1051 题解: 强连通缩点得到DAG图,将图转置一下,对入度为零的点跑dfs看看能不能访问 ...

  7. bzoj 1051: [HAOI2006]受欢迎的牛 (Tarjan 缩点)

    链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1051 思路: 首先用Tarjan把环缩成点,要想收到所有人的欢迎,那么这个点的出度必为0,且 ...

  8. bzoj 1051 [HAOI2006]受欢迎的牛(tarjan缩点)

    题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1051 题解:缩点之后判断出度为0的有几个,只有一个那么输出那个强连通块的点数,否者 ...

  9. 【BZOJ 1051】 1051: [HAOI2006]受欢迎的牛 (SCC)

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

随机推荐

  1. BNU 13289 Energetic Pandas DP

     Energetic Pandas  There are n bamboos of different weights Wi. There are n pandas of different capa ...

  2. oc52--autorelease1

    // // main.m /* autorelease也是用于内存管理的,给对象发送autorelease消息就会把对象放入autoreleasepool这个池子中,当池子销毁的时候会对池子里面的所有 ...

  3. CockroachDB——类似spanner的开源版,底层使用rocksdb存储,mvcc,支持事务,raft一致性,licence是CockroachDB Community License Agreement

    摘自:https://github.com/cockroachdb/cockroach/blob/master/docs/design.md CockroachDB is a distributed ...

  4. 2017 Multi-University Training Contest - Team 2 &&hdu 6050 Funny Function

    Funny Function Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  5. HQL分页查询

    转自:https://blog.csdn.net/dwenxue/article/details/80460161 [例]雇员信息 分页查询(1)setFirstResult(int firstRes ...

  6. 84. ExtJS下页面显示中文乱码问题

    转自:https://blog.csdn.net/wenminhao/article/details/51198981 最近在学校extjs是,使用js脚本显示中文在html页面中时,中午出现了乱码的 ...

  7. Tunnel Warfare(树状数组+二分)

    http://poj.org/problem?id=2892 题意:输入n,m.n代表数轴的长度,m代表操作数. D x: 摧毁点x Q x: 询问村庄x最左与最右没有被摧毁的点的距离 R  :恢复最 ...

  8. Find them, Catch them(并查集)

    http://poj.org/problem?id=1703 题意:有两个黑帮团伙,共n名团伙成员(不知道属于这两个黑帮中的哪一个).现在警察有一些信息,每条信息包含2个人的编号,如果给出A a b, ...

  9. html5 历史管理

    1.onhashchange:改变hash值来进行历史管理. <!DOCTYPE html> <html> <head> <meta charset=&quo ...

  10. 修改DIV滚动条样式

    /*滚动条样式*/ div::-webkit-scrollbar { /*滚动条整体样式*/ width: 5px; /*高宽分别对应横竖滚动条的尺寸*/ height: 5px; } div::-w ...