(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

目录

题意:传送门

 原题目描述在最下面。

 A认为B优秀,B认为C优秀,则A认为C优秀。问有多少个人被其他所有人认为优秀。

思路:

缩点后,求出度为0的连通分量。当且仅当只有一个连通分量出度为0时输出解,否则输出0.

AC代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#include<cctype>
#include<string>
#include<cmath>
#include<bitset>
#include<cassert>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define fuck(x) cout<<"* "<<x<<"\n"
#define all(x) (x).begin(),(x).end()
#define iis std::ios::sync_with_stdio(false)
using namespace std;
typedef long long LL;
const int N = 1e4+5;
const int M = 1e7+5;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
int n, m;
struct lp{
int v, nex;
}cw[N*20];
int head[N],tot;
int dfn[N],low[N],vis[N],inde;
int qltNum,qltId[N];
vector<int> scc[N];
int stak[N*20],top;
int out[N];
void dfs(int u,int Fa){
dfn[u]=low[u]=++inde;
vis[u]=1;stak[++top]=u;
for(int i=head[u];~i;i=cw[i].nex){
int v = cw[i].v;
//if(v==Fa)continue;
if(!dfn[v]){
dfs(v,u);
low[u]=min(low[u],low[v]);
}else if(vis[v]==1) low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u]){
qltNum++;
int v;
do{
v=stak[top--];
vis[v]=2;
qltId[v]=qltNum;
}while(v!=u);
}
}
void tarjan(){
for(int i=1;i<=n;++i){
if(!dfn[i])dfs(i,-1);
}
}
inline void work(){
for(int i=1;i<=n;++i){
for(int j=head[i];~j;j=cw[j].nex){
if(qltId[i]!=qltId[cw[j].v]){
out[qltId[i]]++;
}
}
}
int num=0,p=1;
for(int i=1;i<=qltNum;++i){
if(out[i]==0){
num++;p=i;
}
}
if(num>1||num==0)printf("0\n");
else{
int ans=0;
for(int i=1;i<=n;++i){
if(qltId[i]==p)ans++;
}
printf("%d\n", ans);
}
}
inline void add(int u,int v){
cw[++tot].v=v;cw[tot].nex=head[u];
head[u]=tot;
}
inline void init(){
mme(head,-1);mme(dfn,0);mme(low,0);mme(vis,0);
for(int i=1;i<=n;++i)scc[i].clear();
qltNum=inde=top=0;
tot=-1;
}
inline void read(){
for(int i=0,u,v;i<m;++i){
scanf("%d%d",&u,&v);
add(u,v);
}
}
int main(){
while(~scanf("%d%d", &n,&m)){
init();
read();
tarjan();
work();
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<set>
#include<string>
#include<cmath>
#include<bitset>
#define mme(a,b) memset((a),(b),sizeof((a)))
#define precision(x,d) cout<<fixed<<setprecision(d)<<x<<"\n"
#define iis std::ios::sync_with_stdio(false)
#define lowbit(x) (x&(-x))
using namespace std;
typedef long long LL;
typedef unsigned long long uLL;
const int N = 10005;
const int M = 490005;
const int INF = 0x3f3f3f3f;
int n,m,tot;
vector<int> G[N],GT[N];
int post[N],vis[N],inde;
int qltNum,qltId[N];
int out[N];
void init(){
for(int i=1;i<=n;++i){
G[i].clear();GT[i].clear();
}
inde=qltNum=0;
mme(vis,0);mme(out,0);
}
void dfs1(int u){
int len = G[u].size();
vis[u]=1;
for(int i=0;i<len;++i){
int v = G[u][i];
if(!vis[v])dfs1(v);
}
post[++inde]=u;
}
void dfs2(int u){
int len = GT[u].size();
vis[u]=0;qltId[u]=qltNum;
for(int i=0;i<len;++i){
int v = GT[u][i];
if(vis[v])dfs2(v);
}
}
void kosaraju(){
for(int i=1;i<=n;++i){
if(!vis[i])dfs1(i);
}
for(int i=inde;i>0;--i){
if(vis[post[i]]){
qltNum++;
dfs2(post[i]);
}
}
for(int i=1;i<=n;++i){
int len = G[i].size();
for(int j=0;j<len;++j){
int v = G[i][j];
if(qltId[i]!=qltId[v]){
out[qltId[i]]++;
}
}
}
int cnt=0,ans=-1;
for(int i=1;i<=qltNum;++i){
if(out[i]==0){
cnt++;ans=i;
}
}
if(cnt!=1)printf("0\n");
else{
int sum=0;
for(int i=1;i<=n;++i){
if(ans==qltId[i]){
sum++;
}
}
printf("%d\n", sum);
}
}
int main(){
while(~scanf("%d%d",&n,&m)){
init();
for(int i=0,u,v;i<m;++i){
scanf("%d%d",&u,&v);
G[u].push_back(v);
GT[v].push_back(u);
}
kosaraju();
}
return 0;
}

####原题目描述:
Description

Every cow's dream is to become the most popular cow in the herd. In a herd of N (1 <= N <= 10,000) cows, you are given up to M (1 <= M <= 50,000) ordered pairs of the form (A, B) that tell you that cow A thinks that cow B is popular. Since popularity is transitive, if A thinks B is popular and B thinks C is popular, then A will also think that C is

popular, even if this is not explicitly specified by an ordered pair in the input. Your task is to compute the number of cows that are considered popular by every other cow.

Input

  • Line 1: Two space-separated integers, N and M

  • Lines 2..1+M: Two space-separated numbers A and B, meaning that A thinks B is popular.

    Output

  • Line 1: A single integer that is the number of cows who are considered popular by every other cow.

    Sample Input

3 3

1 2

2 1

2 3

Sample Output

1

Hint

Cow 3 is the only cow of high popularity.

Source

USACO 2003 Fall

POJ2186-Tarjan-kosaraju-缩点的更多相关文章

  1. [poj2762] Going from u to v or from v to u?(Kosaraju缩点+拓排)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud     Going from u to v or from v to u? Tim ...

  2. BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1179 题意概括 有一个有向图,每一个节点有一个权值,其中有一些结束点. 现在,你要从S出发,到达任 ...

  3. BZOJ1051 [HAOI2006]受欢迎的牛 Tarjan 强连通缩点

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1051 题意概括 有n只牛,有m个羡慕关系. 羡慕关系具有传递性. 如果A羡慕B,B羡慕C,那么我们 ...

  4. tarjan算法+缩点--cojs 908. 校园网

    cojs 908. 校园网 ★★   输入文件:schlnet.in   输出文件:schlnet.out   简单对比时间限制:1 s   内存限制:128 MB USACO/schlnet(译 b ...

  5. Tarjan的缩点&&割点概述

    What is Tarjan? Tarjan,是一种用来解决图的联通性的一种有效途径,它的一般俗称叫做:缩点.我们首先来设想一下: 如果我们有一个图,其中A,B,C构成一个环,那么我们在某种条件下,如 ...

  6. 半连通分量--Tarjan/Kosaraju算法

    一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...

  7. hdu 1269 迷宫城堡 最简单的联通图题 kosaraju缩点算法

    迷宫城堡 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem Des ...

  8. tarjan算法+缩点:求强连通分量 POJ 2186

    强连通分量:1309. [HAOI2006]受欢迎的牛 ★★   输入文件:cow.in   输出文件:cow.out   简单对比时间限制:1 s   内存限制:128 MB [题目描述] 每一头牛 ...

  9. poj1236 Network of Schools【强连通分量(tarjan)缩点】

    转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html  ---by 墨染之樱花 [题目链接]http://poj.org/pr ...

  10. POJ 1236 Network of Schools (tarjan算法+缩点)

    思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...

随机推荐

  1. PHP ftp_delete() 函数

    定义和用法 ftp_delete() 函数删除 FTP 服务器上的一个文件. 如果成功,该函数返回 TRUE.如果失败,则返回 FALSE 和一个警告. 语法 ftp_delete(ftp_conne ...

  2. NX二次开发-Block UI C++界面(表达式)控件的获取(持续补充)

    Expression(表达式)控件的获取 NX9+VS2012 #include <uf.h> #include <uf_modl.h> UF_initialize(); // ...

  3. 带头节点的单链表-------C语言实现

    /***************************************************** Author:Simon_Kly Version:0.1 Date:20170520 De ...

  4. jdk tomcat的项目版本一致操作

    操作jdk版本以及tomcat版本:右键项目--buildpath--configure buildpath...---project Facets---libraries---add/选中remov ...

  5. Dubbo入门到精通学习笔记(九):简易版支付系统介绍、部署(单节点)

    文章目录 部署(单节点) 一.前期准备 二.对部署环境进行规划 创建数据库 调整公共配置文件 应用部署前期准备 部署服务 部署 Web 应用 部署定时任务 一. 工程结构 第三方支付系统架构 pay- ...

  6. HDU 6656 Kejin Player (期望DP 逆元)

    2019 杭电多校 7 1011 题目链接:HDU 6656 比赛链接:2019 Multi-University Training Contest 7 Problem Description Cub ...

  7. mysql 命令 常用操作

    导出sql文件:mysqldump -h localhost -u root -p xsxj > d:\xsxj.sql    导入sql文件  MySQL> source   d:/my ...

  8. JDK8之新特性扩展篇

    之前分篇章讲了一些JKD8中添加的新特性,还有一些新特性这里也一并讲下. BASE64 base64编码解码已经被加入到了jdk8中了. import java.nio.charset.Standar ...

  9. hdu6395 /// 优先队列dijkstra

    题目大意: 给定无向图的n m为点数和边数 接下来m行给定u v id表示点u到点v间有一条编号为id的边 当由一条边走到另一条边 而两条边的编号不同时 费用+1 优先队列跑dijkstra最短路 按 ...

  10. beforeEach的深入研究,及beforeEach和beforeRouteEnter区别?

    之前一直困惑它俩的区别,也没找到合适的文档,直到有天看到一篇博客,一起来学习下: 之前是在created钩子函数里面,发现这是在今天当前页面之后了.先回顾一下钩子函数beforeEach const ...