1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 8161  Solved: 4460

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
 
题解:
这题一开始我用并查集乱搞了一下,结果搞出来了...
如果一头牛受欢迎,那么他所有喜欢的牛都是被所有牛认为受欢迎的。那么我们关键就是找出第一头被所有牛认为受欢迎的牛。
在合并集合的时候用sum数组维护喜欢父亲结点的个数,当个数等于n时我们就找到一头牛了。
之后再用个bfs来求就好了。
 
代码如下:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <queue>
using namespace std; const int N = ,M = ;
int n,m,tot;
int head[N],f[N],sum[N],vis[N];
map<int,map<int,int> > mp;
struct Edge{
int u,v,next ;
}e[M];
void adde(int u,int v){
e[++tot].u=u;e[tot].v=v;
e[tot].next=head[u];
head[u]=tot;
}
int find(int x){
return f[x]==x ? f[x] : f[x]=find(f[x]);
}
int main(){
cin>>n>>m;
int st=;
memset(head,-,sizeof(head));
for(int i=;i<=N-;i++) f[i]=i,sum[i]=;
for(int i=,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
if(!mp[u][v]){
mp[u][v]=;
adde(u,v);
int fx=find(u),fy=find(v);
if(fx!=fy){
f[fx]=fy;
sum[fy]+=sum[fx];
if(sum[fy]==n) st=fy;
}
}
}
int cnt =;
if(!st)puts("");
else{
queue<int> q;
q.push(st);vis[st]=;
while(!q.empty()){
int u=q.front();q.pop();
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!vis[v]){
vis[v]=;
q.push(v);
cnt++;
}
}
}
printf("%d\n",cnt);
}
return ;
}

再来说一下tarjan。

先用tarjan缩点,然后重新构图,找到出度为0的点那么这里面所有的牛都是被所有牛认为受欢迎的。

注意一下构图后不连通的情况就好了。

代码如下:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <stack>
using namespace std; const int N = ,M = ;
int n,m,tot,num,T;
int head[N],dfn[N],low[N],vis[N],scc[N];
struct Edge{
int u,v,next ;
}e[M];
void adde(int u,int v){
e[++tot].u=u;e[tot].v=v;
e[tot].next=head[u];head[u]=tot ;
}
stack <int> s;
void Tanjan(int u){
dfn[u]=low[u]=++T;vis[u]=;
s.push(u);
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(!vis[v]){
Tanjan(v);
low[u]=min(low[u],low[v]);
}else{
low[u]=min(low[u],dfn[v]);
}
}
if(low[u]==dfn[u]){
num++;int now;
do{
now = s.top();s.pop();
scc[now]=num;
}while(!s.empty() && now!=u);
}
}
int main(){
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));
for(int i=,u,v;i<=m;i++){
scanf("%d%d",&u,&v);
adde(u,v);
}
for(int i=;i<=n;i++){
if(!vis[i]) Tanjan(i);
}
int out[N]={},in[N]={};
for(int u=;u<=n;u++){
for(int i=head[u];i!=-;i=e[i].next){
int v=e[i].v;
if(scc[u]!=scc[v]){
out[scc[u]]++;
in[scc[v]]++;
}
}
}
int cnt=,ans=,tag;
for(int i=;i<=num;i++) if(!out[i]) cnt++,tag=i;
if(cnt==){
for(int i=;i<=n;i++) if(scc[i]==tag) ans++;
printf("%d",ans);
}else puts("");
return ;
}

BZOJ1051:受欢迎的牛(并查集 / Tarjan)的更多相关文章

  1. BZOJ1051 受欢迎的牛

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

  2. p2341&bzoj1051 受欢迎的牛

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

  3. bzoj1051受欢迎的牛(Tarjan)

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

  4. HDU ACM 2586 How far away ?LCA-&gt;并查集+Tarjan(离线)算法

    题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w.有m次询问,每次询问房子a,b之间的距离是多少. 分析:近期公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次 ...

  5. 关于并查集的路径压缩(Path Compress)优化

    之前在CSDN看到一篇很受欢迎的讲解并查集的博文,其中自然用到了路径压缩: int pre[1000]; int find(int x){ int root = x; while(pre[root]! ...

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

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

  7. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  8. 【BZOJ1051】[HAOI2006]受欢迎的牛

    [BZOJ1051][HAOI2006]受欢迎的牛 题面 bzoj 洛谷 题解 假如\(A\)喜欢\(B\)就连一条\(A\)到\(B\)的边 然后缩点,如果图不连通就\(Impossible\) 否 ...

  9. 牛客练习赛16 C 任意点【并查集/DFS/建图模型】

    链接:https://www.nowcoder.com/acm/contest/84/C 来源:牛客网 题目描述 平面上有若干个点,从每个点出发,你可以往东南西北任意方向走,直到碰到另一个点,然后才可 ...

随机推荐

  1. linux实现DNS轮询实现负载平衡

    DNS 轮询机制会受到多方面的影响,如:A记录的TTL时间长短的影响:别的 DNS 服务器 Cache 的影响:windows 客户端也有一个DNS Cache.这些都会影响 DNS 轮询的效果.因此 ...

  2. 预防跨站脚本(xss)

    对xss的防护方法结合在两点上输入和输出,一是严格控制用户表单的输入,验证所有输入数据,有效监测到攻击,go web表单中涉及到.二是对所有输出的数据进行处理,防止已成功注入的脚本在浏览器端运行. 在 ...

  3. python2.7入门--- 日期和时间

        Python 程序能用很多方式处理日期和时间,转换日期格式是一个常见的功能.我们今天就来看一下这方面,首先得知道,Python 提供了一个 time 和 calendar 模块可以用于格式化日 ...

  4. python2.7入门---网络编程(socket)

        Python 提供了两个级别访问的网络服务: 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法. 高级别 ...

  5. Encrypted bootloader (程序BIN文件加密及在线升级)

    了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程序). 在上一个博客随笔,我介 ...

  6. thrift服务端到客户端开发简单示例

    (1)首先我们在服务器端写个helloworld.thrift文件,如下所示: service HelloWorld{ string ping(1: string name), string getp ...

  7. python保留关键字和常用关键字

    python保留关键字和常用关键字如下: 上图是python3中的关键字,python2.7中的关键字部分会有区别,具体在自己打印输出查看: import keyword print ' '.join ...

  8. 一次和别人争吵一个按钮,点击后显示导航;再点击不显示的效果,是否一定以及必须用js?

    事情经过是这样的,我们组一个说话很喜欢用一定,肯定的哥们,吃午饭的时候拿了自己做的一个UI库,头部有一个按钮 点击展开,再次点击收缩,他意思说一个按钮无法记录点击状态,必须使用js.然后我看了一眼,心 ...

  9. [转]Git,SVN的优缺点及适合的范围,开源项目?公司项目?

    使用git不久,粗浅理解: 1)适用对象不同.Git适用于参与开源项目的开发者.他们由于水平高,更在乎的是效率而不是易用性.Svn则不同,它适合普通的公司开发团队.使用起来更加容易. 2)使用的场合不 ...

  10. Sqlite Datetime类型详解

    日期和时间函数 date(timestring, modifier, modifier, ...) time(timestring, modifier, modifier, ...) datetime ...