POJ2186-Tarjan-kosaraju-缩点
(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦
目录
题意:传送门
原题目描述在最下面。
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.
OutputLine 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-缩点的更多相关文章
- [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 ...
- BZOJ1179 [Apio2009]Atm Tarjan 强连通缩点 动态规划
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1179 题意概括 有一个有向图,每一个节点有一个权值,其中有一些结束点. 现在,你要从S出发,到达任 ...
- BZOJ1051 [HAOI2006]受欢迎的牛 Tarjan 强连通缩点
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1051 题意概括 有n只牛,有m个羡慕关系. 羡慕关系具有传递性. 如果A羡慕B,B羡慕C,那么我们 ...
- tarjan算法+缩点--cojs 908. 校园网
cojs 908. 校园网 ★★ 输入文件:schlnet.in 输出文件:schlnet.out 简单对比时间限制:1 s 内存限制:128 MB USACO/schlnet(译 b ...
- Tarjan的缩点&&割点概述
What is Tarjan? Tarjan,是一种用来解决图的联通性的一种有效途径,它的一般俗称叫做:缩点.我们首先来设想一下: 如果我们有一个图,其中A,B,C构成一个环,那么我们在某种条件下,如 ...
- 半连通分量--Tarjan/Kosaraju算法
一个有向图称为半连通(Semi-Connected),满足:对于图中任两点u,v,存在一条u到v的有向路径或者从v到u的有向路径. 若满足,则称G’是G的一个导出子图. 若G’是G的导出子图,且G’半 ...
- hdu 1269 迷宫城堡 最简单的联通图题 kosaraju缩点算法
迷宫城堡 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem Des ...
- tarjan算法+缩点:求强连通分量 POJ 2186
强连通分量:1309. [HAOI2006]受欢迎的牛 ★★ 输入文件:cow.in 输出文件:cow.out 简单对比时间限制:1 s 内存限制:128 MB [题目描述] 每一头牛 ...
- poj1236 Network of Schools【强连通分量(tarjan)缩点】
转载请注明出处,谢谢:http://www.cnblogs.com/KirisameMarisa/p/4316263.html ---by 墨染之樱花 [题目链接]http://poj.org/pr ...
- POJ 1236 Network of Schools (tarjan算法+缩点)
思路:使用tarjan求强连通分量并进行缩点,判断所有入度为0的点,这个点就是必须要给予文件的点,分别计算出度,入度为零的点的个数,取二者的最大值就是把这个图变成强连通需要加的边数. 一个取值需要讨论 ...
随机推荐
- php重定向说明
302 临时重定向 header("location:http://api.com/headline?" . http_build_query($_REQUEST)); 301 ...
- linux IPC socket
套接字是通讯端点的抽象 创建一个套接字 #include <sys/types.h> #include <sys/socket.h> int socket(int domain ...
- 51nod-1515 明辨是非——并查集
给n组操作,每组操作形式为x y p. 当p为1时,如果第x变量和第y个变量可以相等,则输出YES,并限制他们相等:否则输出NO,并忽略此次操作. 当p为0时,如果第x变量和第y个变量可以不相等,则输 ...
- SDNU 1217 CD收藏——并查集
Description lmh平常爱听歌,所以买了很多的CD来收藏,但是因为平常整理不当,所以忘记了这些CD的歌手是谁.现在他想知道他到底收藏了多少位歌手的专辑,于是他想了一个办法,同时拿出两 ...
- mysql 审核
https://javinjunfeng.top/technicalstack/database/43
- redis 配置文件aof配置
redis 配置文件aof配置: bind 127.0.0.1 port 6379 daemonize yes dbfilename dump.rdb dir /new_renpeng/redis/ ...
- Django框架(九)—— 单表增删改查,在Python脚本中调用Django环境
目录 单表增删改查,在Python脚本中调用Django环境 一.数据库连接配置 二.orm创建表和字段 三.单表增删改查 1.增加数据 2.删除数据 3.修改数据 4.查询数据 四.在Python脚 ...
- centos7.2下快速安装zabbix4.0
本笔记是基于CentOS 7.2下最小化安装的操作系统搭建的Zabbix4.0环境,主要用于做一些企业路由器和交换机等设备的运行状态监控. 1.安装epel源 yum -y install epel- ...
- 调用API接口,查询手机号码归属地(1)
使用https://www.juhe.cn/提供的接口,查询归属地 在官网注册key即可使用. 代码如下 #!/usr/bin/python # -*- coding: utf-8 -*- impor ...
- Spring MVC源码分析(三):SpringMVC的HandlerMapping和HandlerAdapter的体系结构设计与实现
概述在我的上一篇文章:Spring源码分析(三):DispatcherServlet的设计与实现中提到,DispatcherServlet在接收到客户端请求时,会遍历DispatcherServlet ...