洛谷 P2341 [HAOI2006]受欢迎的牛|【模板】强连通分量
题目传送门
解题思路:
先求强联通分量,缩点,然后统计新图中有几个点出度为0,如果大于1个,则说明这不是一个连通图,答案即为0.否则入度为0的那个强连通分量的点数即为答案
AC代码:
#include<iostream>
#include<cstdio>
#include<stack>
#include<set> using namespace std; int daan,n,m,head[],tot;
int dfn[],low[],sum,rp;
int belong[],_head[],num[];
bool vis[];
struct kk{
int to,next;
}e[],a[];
stack<int> s;
set<int> ans[]; inline void add(int x,int y) {
e[++tot].to = y;
e[tot].next = head[x];
head[x] = tot;
} inline void tarjan(int x) {
dfn[x] = low[x] = ++sum;
int v;
s.push(x);
vis[x] = ;
for(int i = head[x];i != ; i = e[i].next) {
v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[x] = min(low[x],low[v]);
}
else if(vis[x])
low[x] = min(low[x],dfn[v]);
}
if(dfn[x] == low[x]) {
rp++;
do {
v = s.top();
s.pop();
belong[v] = rp;
num[rp]++;
vis[x] = false;
}
while(v != x);
}
} inline void _add(int x,int y) {
a[++tot].to = y;
a[tot].next = _head[x];
_head[x] = tot;
} inline void findin() {
for(int i = ;i <= rp; i++)
for(int j = _head[i];j != ; j = a[j].next) {
int o = a[j].to;
ans[i].insert(o);
}
} int main() {
scanf("%d%d",&n,&m);
for(int i = ;i <= m; i++) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i = ;i <= n; i++)
if(!dfn[i]) //求强连通分量
tarjan(i);
tot = ;
for(int i = ;i <= n; i++)//构建新图,其实没啥必要
for(int j = head[i];j != ; j = e[j].next)
if(belong[i] != belong[e[j].to])
_add(belong[i],belong[e[j].to]);
findin();
for(int i = ;i <= rp; i++)//找入度为0的点
if(ans[i].size() == ) {
if(daan != ) {
printf("");
return ;
}
daan = i;
}
printf("%d",num[daan]);
return ;
}
第一次的做法,用了set,较麻烦
#include<iostream>
#include<cstdio>
#include<stack>
#include<set> using namespace std; int daan,n,m,head[],tot;
int _out[],dfn[],low[];
int sum,rp,belong[];
int _head[],num[];
bool vis[];
struct kk{
int to,next;
}e[],a[];
stack<int> s; inline void add(int x,int y) {
e[++tot].to = y;
e[tot].next = head[x];
head[x] = tot;
} inline void tarjan(int x) {
dfn[x] = low[x] = ++sum;
int v;
s.push(x);
vis[x] = ;
for(int i = head[x];i != ; i = e[i].next) {
v = e[i].to;
if(!dfn[v]) {
tarjan(v);
low[x] = min(low[x],low[v]);
}
else if(vis[x])
low[x] = min(low[x],dfn[v]);
}
if(dfn[x] == low[x]) {
rp++;
do {
v = s.top();
s.pop();
belong[v] = rp;
num[rp]++;
vis[x] = false;
}
while(v != x);
}
} inline void _add(int x,int y) {
a[++tot].to = y;
a[tot].next = _head[x];
_head[x] = tot;
} int main() {
scanf("%d%d",&n,&m);
for(int i = ;i <= m; i++) {
int x,y;
scanf("%d%d",&x,&y);
add(x,y);
}
for(int i = ;i <= n; i++)
if(!dfn[i])
tarjan(i);
tot = ;
for(int i = ;i <= n; i++)
for(int j = head[i];j != ; j = e[j].next)
if(belong[i] != belong[e[j].to])
_out[belong[i]]++;
for(int i = ;i <= rp; i++)
if(_out[i] == ) {
if(daan != ) {
printf("");
return ;
}
daan = i;
}
printf("%d",num[daan]);
return ;
}
改进后的代码,发现不用set,比较精简
洛谷 P2341 [HAOI2006]受欢迎的牛|【模板】强连通分量的更多相关文章
- 【题解】洛谷P2341 [HAOI2006]受欢迎的牛(强连通分量)
洛谷P2341:https://www.luogu.org/problemnew/show/P2341 前言 这题看错题目 足足花了将近5小时提交了15次 在一位dalao的提醒下才AC了 记得要看清 ...
- 洛谷 P2341 [HAOI2006]受欢迎的牛 解题报告
P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的"喜欢&q ...
- 洛谷——P2341 [HAOI2006]受欢迎的牛//POJ2186:Popular Cows
P2341 [HAOI2006]受欢迎的牛/POJ2186:Popular Cows 题目背景 本题测试数据已修复. 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所 ...
- 洛谷P2341 [HAOI2006]受欢迎的牛 (Tarjan,SCC缩点)
P2341 [HAOI2006]受欢迎的牛|[模板]强连通分量 https://www.luogu.org/problem/P2341 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就 ...
- 【模板】Tarjan缩点,强连通分量 洛谷P2341 [HAOI2006]受欢迎的牛 [2017年6月计划 强连通分量01]
P2341 [HAOI2006]受欢迎的牛 题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的 ...
- 洛谷P2341 [HAOI2006]受欢迎的牛|【模板】强连通分量
https://www.luogu.org/problem/P2341 缩点之后唯一 一个出度为0的点 #include<cstdio> #include<iostream> ...
- 洛谷 P2341 [HAOI2006]受欢迎的牛
题目描述 每头奶牛都梦想成为牛棚里的明星.被所有奶牛喜欢的奶牛就是一头明星奶牛.所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的.奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C ...
- POJ——T2186 Popular Cows || 洛谷——P2341 [HAOI2006]受欢迎的牛
http://poj.org/problem?id=2186 || https://www.luogu.org/problem/show?pid=2341 Time Limit: 2000MS M ...
- 洛谷 P2341 [HAOI2006]受欢迎的牛 题解
今天学了强连通分量的Tarjan算法,做了这道类似于板子题的题(尽管我调了1.5h).主要的思路是用Tarjan缩点之后,求每个点的入度(实际上是出度,因为我是反着连边的).如果 有且只有一个点的入度 ...
随机推荐
- 2-10 就业课(2.0)-oozie:6、通过oozie执行mr任务,以及执行sqoop任务的解决思路
执行sqoop任务的解决思路(目前的问题是sqoop只安装在node03上,而oozie会随机分配一个节点来执行任务): ======================================= ...
- gojs 部分功能实现
最近做的项目用到了gojs,使用了一段时间发现其功能特别强大,先记录下目前自己用到的把 1. 初始化画布 myDiagram = $(go.Diagram, "myDiagramDiv&qu ...
- 在命令提示符中运行install adb 包名.apk文件 遇到的问题
昨天更新了SDK以后遇到一个奇怪的问题,使用eclipse直接运行程序到手机没有问题,但是如果将程序打包之后在命令提示符中执行adb install 包名.apk 就会报错:adb server is ...
- PHP处理大数据量老用户头像更新的操作--解决数据量大超时的问题
/** * @title 老用户头像更新--每3秒调用一次接口,每次更新10条数据 * @example user/createHeadPicForOldUser? * @method GET * @ ...
- vue-i18n多语言文件归类的两种方法
1.按语言类型归类 流行的做法是按照语言对文件进行归类,目录结构类似于: --lang ----en ------test.json --------"abc": "ab ...
- 04 MySQL数据类型
MySQL支持的数据类型 1.数值类型: a.整数类型 TINYINT 1字节 有符号(-128~127); 无符号(0~255) SMALLINT 2字节 有符号(-3276 ...
- 二十三、SAP中内表的修改
一.通过MODIFY关键字来修改内表的内容,it相当于全部内容,wa相当于一条内容 二.效果如下
- 在Windows中安装vim
这篇文章主要教大家如何在Windows系统下安装最好用的编辑器VIM 来自百度百科的介绍: Vim是一个类似于Vi的著名的功能强大.高度可定制的文本编辑器,在Vi的基础上改进和增加了很多特性. VIM ...
- ActiveMQ消息队列和SignalR之日志实时监控及警报小实例
主要技术: log4net-生成日志. ActiveMQ-生成日志的时候发送消息,并实时监控日志. SignalR-将ActiveMQ监控的日志实时显示到浏览器上,而不用刷新浏览器. 小实例介绍: 左 ...
- Android Studio模拟器无法访问网络
Android Studio3.5 模拟器无法访问网络的原因?