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. Java学习笔记三:Java的变量、常量、变量的类型及使用规则

    Java的变量.常量.变量的类型及使用规则 每一种语言都有一些具有特殊用途的词,Java也不例外,它们被称为关键字.关键字对 Java 的编译器有着特殊的意义. 一:Java中的关键字: 注:Java ...

  2. 一些matlab教程资源收藏,使用matlab编程的人还是挺多的

    Matlab教程专题资源免费下载整理合集收藏 <MATLAB从入门到精通>高清文字版[PDF] 103.9MB 简体中文 <矩阵实验室>(Mathworks.Matlab.R2 ...

  3. POJ2186 强连通分量+缩点

    Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 40234   Accepted: 16388 De ...

  4. System.Speech使用

    使用微软语音库 使用微软语音库可以很快速的制作一个小应用,比如一个唐诗的朗诵工具.本示例也是使用微软语音库,制作了一个唐诗宋词朗诵的应用,仅供加深学习印象 首先是要引入System.Speech库 然 ...

  5. Kuernetes-设计架构(二)

    Kubernetes设计架构 Kubernetes集群包含有节点代理kubelet和Master组件(APIs,scheduler.etc),一切都基于分布式的存储系统.Kubernetes架构图: ...

  6. hive报错:Caused by: ERROR XBM0H: Directory /var/lib/hive/metastore/metastore_db cannot be created.

    在cdh集群中,删除之前的hive服务,然后将hive添加到其他节点,然后再通过hive客户端连接hive报错: Caused by: ERROR XJ041: Failed to create da ...

  7. 预装win8的笔记本如何重装win7

    测试电脑联想T440. 开机按F1,然后Enter,进入Bios设置. 先关闭Secure Boot,然后设置为Legacy Boot. 之后才能设置U盘为第一启动盘. 进入老毛桃的PE系统,使用Di ...

  8. 小程序如何去掉button组件的边框

    小程序获取用户授权不再支持wx.getUserInfo方法,改为用button获取,格式如下 <button class="btn btn" open-type=" ...

  9. MQTT 开源代理mosquitto的网络层封装相当sucks

    最近学习MQTT协议,选择了当前比较流行的MQTT Broker “mosquitto”,但是在阅读代码过程中发现其网络底层库封装的相当差劲. 对于MQTT协议的变长头长度的读取上,基本上采取每次一个 ...

  10. linux学习总结----对象

    内置对象: Date new Date() --->系统当前时间 var d=new Date() d.getFullYear() getMonth() getDay() getDate() g ...