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. struts2学习

    struts2是一种基于mvc模式的轻量级web框架,它本质上相当于一个servlet,在mvc设计模式中,struts2作为控制器(Controller)来建立模型与视图的数据交互,struts2采 ...

  2. Redis 在springBoot中的一个使用示例

    在现系统中使用了一个字典表,更新或插入字典表需要做Redis缓存 @Override @Cache(name = Constants.REDIS_PREFIX_DIC, desc = "变更 ...

  3. MFC接收ShellExecute多个参数

    在应用程序开发过程中,我们经常需要带参数启动另一个执行程序,如何传递多个参数,如何解析多个参数呢?   传参数 传递参数可使用ShellExecute函数,示例如下: ShellExecute(NUL ...

  4. 41-Individual authentication 模板

    1-创建项目,进入vscode控制台,输出如下命令, uld表示指定mssqllocaldb E:\coding\netcore>dotnet new mvc -au Individual -u ...

  5. TreeMap与LinkedHashMap的区别

    TreeMap是根据元素的内部比较器进行排序的,它可以根据key值的大小排序: LinkedHashMap是保持存放顺序的. TreeMap采用红黑树算法,遍历效率高: LinkedHashMap采用 ...

  6. Spring事务:一种编程式事务,三种声明式事务

    事务隔离级别 隔离级别是指若干个并发的事务之间的隔离程度.TransactionDefinition 接口中定义了五个表示隔离级别的常量: TransactionDefinition.ISOLATIO ...

  7. webapi到处excel

    最近项目用的webapi前几天做了个导出excel功能,给大家分享下,自己也记录下... 在用的过程中,可以直接请求就可以得到下载的excel文件,在实际的项目中可以通过js打开新页面,encodeU ...

  8. ExtJs工具篇(3)——Aptana Studio3乱码的问题

            在Aptana Studio里面使用,发现输入的中文是乱码,在浏览器中浏览也是乱码,想着肯定是编码的问题,但是一直没有找到在那个地方设置.以为汉化后就可以了,没想到汉化后竟然还是乱码, ...

  9. runtime总结 iOS

    Runtime的特性主要是消息(方法)传递,如果消息(方法)在对象中找不到,就进行转发,具体怎么实现的呢.我们从下面几个方面探寻Runtime的实现机制. Runtime介绍 Runtime消息传递 ...

  10. localStorage简析

    声明:引用自http://www.cnblogs.com/st-leslie/p/5617130.html 一.什么是localStorage.sessionStorage 在HTML5中,新加入了一 ...