题目直接摆在这里!

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 4438  Solved: 2353
[Submit][Status][Discuss]

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

Source

[Submit][Status][Discuss]

这道题和codevs2822爱在心中类似,也是一道tarjan练手题,所以具体的tarjan板子我就不再贴出来了。

这道题的思路也可以和codevs2822一样的,使用tarjan+SPFA,但是由于本人太懒,不想再打140行代码,就换了另一种思路。

正解:tarjan缩点

具体做法:

第一步,先读入数据建边;

第二步,开始跑tarjan,别忘记在tarjan过程中要缩点,接下来的过程要用到。(所谓缩点,就是把每个点都归到一个强联通块里面,对强联通块进行操作)

第三步:根据m个边的关系,统计每个强联通块的出度。

第四步:统计出度为0的强联通块的个数,若为1,则输出次强联通块组成元素个数,否则输出0。(这里才是这道题目核心的思想,想一想为什么,其实很简单)。

先贴上代码(建议大家不要用vector这种东西,数据结构尽量手写)

 #include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <stack>
using namespace std;
int get_num(){
int num = ;
char c;
bool flag = false;
while((c = getchar()) == ' ' || c == '\r' || c == '\n');
if(c == '-')
flag = true;
else num = c - '';
while(isdigit(c = getchar()))
num = num * + c - '';
return (flag ? - : ) * num;
}
const int maxn = 1e4 + ;
const int maxm = 5e4 + ;
int n,m,h[maxn],sccno[maxn],scc_cnt,id[maxn],sum,r[maxn],dfn[maxn],low[maxn],dfs_clock,ans,pos;
stack<int>s;
struct edge{
int fr,to,next;
}edges[maxm << ];
void addedge(int u,int v){
edges[sum].fr = u;
edges[sum].to = v;
edges[sum].next = h[u];
h[u] = sum++;
}
void init(){
memset(id,,sizeof(id));
memset(sccno,,sizeof(sccno));
memset(r,,sizeof(r));
memset(h,-,sizeof(h));
memset(edges,,sizeof(edges));
sum = ;
dfs_clock = ;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
}
void tarjan(int u){
dfn[u] = low[u] = ++dfs_clock;
s.push(u);
for(int i = h[u];i != -;i = edges[i].next){
edge e = edges[i];
if(!dfn[e.to]){
tarjan(e.to);
low[u] = min(low[u],low[e.to]);
}
else if(!id[e.to])
low[u] = min(low[u],dfn[e.to]);
}
if(low[u] == dfn[u]){
scc_cnt++;
while(true){
int x = s.top();
s.pop();
sccno[scc_cnt] += ;
id[x] = scc_cnt;
if(x == u)break;
}
}
return;
}
void find_tarjan(){
for(int i = ;i <= n;++i){
if(!dfn[i])
tarjan(i);
}
return;
}
int main(){
int a,b;
init();
n = get_num();
m = get_num();
for(int i = ;i <= m;++i){
a = get_num();
b = get_num();
addedge(a,b);
}
find_tarjan();
for(int i = ;i < sum;++i){
int x = edges[i].fr;
int y = edges[i].to;
if(id[x] != id[y])
r[id[x]]++;
}
ans = ;
for(int i = ;i <= scc_cnt;++i){
if(r[i] == ){
if(!ans)
ans = sccno[i];
else{
ans = ;
break;
}
}
}
printf("%d\n",ans);
return ;
}

这次解题报告就写到这里吧,NOIP倒计时两个月,祝大家能考个好成绩!

BZOJ 1051 最受欢迎的牛 解题报告的更多相关文章

  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 (强连通) 受欢迎的牛

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

  6. 洛谷 P2341 [HAOI2006]受欢迎的牛 解题报告

    P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢&q ...

  7. 洛谷 P2341 BZOJ 1051 [HAOI2006]受欢迎的牛

    题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C ...

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

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

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

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

随机推荐

  1. JAVA-集合作业-已知有十六支男子足球队参加2008 北京奥运会。写一个程序,把这16 支球队随机分为4 个组。采用List集合和随机数

    第二题 已知有十六支男子足球队参加2008 北京奥运会.写一个程序,把这16 支球队随机分为4 个组.采用List集合和随机数 2008 北京奥运会男足参赛国家: 科特迪瓦,阿根廷,澳大利亚,塞尔维亚 ...

  2. Java基础-接口.编写2个接口:InterfaceA和InterfaceB;在接口InterfaceA中有个方法void printCapitalLetter();在接口InterfaceB中有个方法void printLowercaseLetter();然 后写一个类Print实现接口InterfaceA和InterfaceB,要求 方法 实现输出大写英文字母表的功能,printLowerca

    #34.编写2个接口:InterfaceA和InterfaceB:在接口InterfaceA中有个方法void printCapitalLetter():在接口InterfaceB中有个方法void ...

  3. CSS颜色模式转换器的实现

    前面的话 在CSS中,颜色的表示方式主要包括关键字.16进制.RGB模式.RGBA模式.HSL模式.HSLA模式.关于颜色模式的详细信息移步至此.本文就16进制.RGB模式及HSL模式的互相转换进行实 ...

  4. Kruskal算法(三)之 Java详解

    前面分别通过C和C++实现了克鲁斯卡尔,本文介绍克鲁斯卡尔的Java实现. 目录 1. 最小生成树 2. 克鲁斯卡尔算法介绍 3. 克鲁斯卡尔算法图解 4. 克鲁斯卡尔算法分析 5. 克鲁斯卡尔算法的 ...

  5. NIO的一坑一惑小记

    前言 不知不觉,已那么长时间没有更新东西了,说来真是汗颜啊.(主要是最近在技术上豁然开朗的感觉越来越少了-_-|||) 最近一直在学习Linux相关的东西.又一次接触到了I/O复用模型(select/ ...

  6. Halcon与opencv格式的转换

    IplImage* ImageProcess::HImageToIplImage(Hobject &Hobj) { IplImage* pImage; HTuple htChannels; c ...

  7. Django之Form、CSRF、cookie和session

    Django是一个大而全的web框架,为我们提供了很多实用的功能,本文主要介绍Form.CSRF.cookie和session 一.Form 在web页面中form表单是重要的组成部分,为了数据安全和 ...

  8. 跟着官网的例子学Reacjs (一)FilterableProductTable

    最近开始学习React,发现最好的方法不是看这个书那个书,而是直接上官网,一步步的跟着学习,真的获益匪浅.许多翻译的书上漏掉的知识点都可以学到. 入门的一些准备工作可以参照官网的步骤,引入依赖的核心包 ...

  9. Oracle Flashback和RMAN示例

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5346833.html 环境: Windows 10 专业版 Oracle Database 12c R ...

  10. 【转载】ASP.NET MVC Web API 学习笔记---第一个Web API程序

    1. Web API简单说明 近来很多大型的平台都公开了Web API.比如百度地图 Web API,做过地图相关的人都熟悉.公开服务这种方式可以使它易于与各种各样的设备和客户端平台集成功能,以及通过 ...