POJ2186 Popular Cows 题解 强连通分量
题目链接:http://poj.org/problem?id=2186
题目大意:
每头牛都想成为牛群中的红人。
给定N头牛的牛群和M个有序对(A, B),(A, B)表示牛A认为牛B是红人;
该关系具有传递性,所以如果牛A认为牛B是红人,牛B认为牛C是红人,那么牛A也认为牛C是红人。
不过,给定的有序对中可能包含(A, B)和(B, C),但不包含(A, C)。
求被其他所有牛认为是红人的牛的总数。
题目分析(引自 https://www.cnblogs.com/violet-acmer/p/9740737.html):
考虑以牛为顶点的有向图,对每个有序对(A, B)连一条从 A到B的有向边;
那么,被其他所有牛认为是红人的牛对应的顶点,也就是从其他所有顶点都可达的顶点。
虽然这可以通过从每个顶点出发搜索求得,但总的复杂度却是O(NM),是不可行的,必须要考虑更为高效的算法。
假设有两头牛A和B都被其他所有牛认为是红人,那么显然,A被B认为是红人,B也被A认为是红人;
即存在一个包含A、B两个顶点的圈,或者说,A、B同属于一个强连通分量。
反之,如果一头牛被其他所有牛认为是红人,那么其所属的强连通分量内的所有牛都被其他所有牛认为是红人。
由此,我们把图进行强连通分量分解后,至多有一个强连通分量满足题目的条件。
而按前面介绍的算法进行强连通分量分解时,我们还能够得到各个强连通分量拓扑排序后的顺序;
唯一可能成为解的只有拓扑序最后的强连通分量。
所以在最后,我们只要检查这个强连通分量是否从所有顶点可达就好了。
思路整理:
1、首先,使用tarjan缩点;
2、其次,检查是否所有点可达
只需要确定是不是缩点后只有一个点的出度为0即可。
如果只有一个点的出度为0,则答案为该点对应的强连通分量中的原图中的点的数量;
否则,答案为 0。
实现代码如下:
#include <iostream>
#include <vector>
#include <stack>
#include <cstring>
using namespace std;
const int maxn = 10010;
int n, dfn[maxn], low[maxn], belong[maxn], idx, cnt;
bool instk[maxn];
stack<int> stk;
vector<int> g[maxn];
void tarjan(int u) {
dfn[u] = low[u] = ++idx;
instk[u] = true;
stk.push(u);
int sz = g[u].size();
for (int i = 0; i < sz; i ++) {
int v = g[u][i];
if (!dfn[v]) {
tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (instk[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u]) {
cnt ++;
int v;
do {
v = stk.top();
stk.pop();
instk[v] = false;
belong[v] = cnt;
} while (u != v);
}
}
void solve() {
memset(dfn, 0, sizeof(dfn));
memset(instk, 0, sizeof(instk));
for (int i = 1; i <= n; i ++) if (!dfn[i]) tarjan(i);
}
int m;
bool vis[maxn];
int main() {
cin >> n >> m;
while (m --) {
int u, v;
cin >> u >> v;
g[u].push_back(v);
}
solve();
for (int u = 1; u <= n; u ++) {
int sz = g[u].size();
for (int i = 0; i < sz; i ++) {
int v = g[u][i];
if (belong[u] != belong[v]) {
vis[ belong[u] ] = true;
}
}
}
int cc = 0, id = -1;
for (int i = 1; i <= cnt; i ++) if (!vis[i]) {
cc ++;
id = i;
}
if (cc != 1) {
cout << 0 << endl;
return 0;
}
int ans = 0;
for (int i = 1; i <= n; i ++) if (belong[i] == id) ans ++;
cout << ans << endl;
return 0;
}
POJ2186 Popular Cows 题解 强连通分量的更多相关文章
- POJ2186 Popular Cows 题解 强连通分量入门题
题目链接:http://poj.org/problem?id=2186 题目大意: 每头牛都想成为牛群中的红人. 给定N头牛的牛群和M个有序对(A, B),(A, B)表示牛A认为牛B是红人: 该关系 ...
- POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 23445 Accepted: 9605 Des ...
- POJ2186 Popular Cows(强连通分量)
题目问一个有向图所有点都能达到的点有几个. 先把图的强连通分量缩点,形成一个DAG,那么DAG“尾巴”(出度0的点)所表示的强连通分量就是解,因为前面的部分都能到达尾巴,但如果有多个尾巴那解就是0了, ...
- poj 2186 Popular Cows 【强连通分量Tarjan算法 + 树问题】
题目地址:http://poj.org/problem?id=2186 Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Sub ...
- poj2186 Popular Cows 题解——S.B.S.
Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 29642 Accepted: 11996 De ...
- POJ 2186 Popular Cows(强连通分量)
[题目链接] http://poj.org/problem?id=2186 [题目大意] 给出一张有向图,问能被所有点到达的点的数量 [题解] 我们发现能成为答案的,只有拓扑序最后的SCC中的所有点, ...
- poj 2186 "Popular Cows"(强连通分量入门题)
传送门 参考资料: [1]:挑战程序设计竞赛 题意: 每头牛都想成为牛群中的红人. 给定N头牛的牛群和M个有序对(A, B),(A, B)表示牛A认为牛B是红人: 该关系具有传递性,所以如果牛A认为牛 ...
- POJ 2186 Popular Cows(强连通分量Kosaraju)
http://poj.org/problem?id=2186 题意: 一个有向图,求出点的个数(任意点可达). 思路: Kosaraju算法的第一次dfs是后序遍历,而第二次遍历时遍历它的反向图,从标 ...
- poj2186 Popular Cows(强连通)
崇拜有传递性.求所有牛都崇拜的牛tarjan算法求强连通. 如果不连通就不存在.如果联通,缩点后唯一一个出度为零的点就是答案,有多个则不存在. #include <vector> #inc ...
随机推荐
- 修改UISearchBar背景
转载:http://blog.csdn.net/favormm/archive/2010/11/30/6045463.aspx UISearchBar是由两个subView组成的,一个是UISearc ...
- 解决 vs 出现Error MC3000 给定编码中的字符无效
在 xaml 写中文注释,发现编译失败 Error MC3000 给定编码中的字符无效 我的 xaml 写了一句代码 <Grid> <!--林德熙--> </Grid&g ...
- redis 清除缓存
- Vue点击事件失效
在做项目时给button添加click事件,发现没反应,但另外写了一个button添加同样的事件,却能触发.原因是使用了better-scroll,默认它会阻止touch事件.所以在配置中需要加上cl ...
- 系统学习前端之FormData详解
FormData 1. 概述 FormData类型其实是在XMLHttpRequest 2级定义的,它是为序列化表以及创建与表单格式相同的数据(当然是用于XHR传输)提供便利. 2. 构造函数 创建一 ...
- 【t079】火星上的加法运算
Time Limit: 1 second Memory Limit: 128 MB [问题描述] 最近欢欢看到一本有关火星的书籍,其中她被一个加法运算所困惑,由于她的运算水平有限,想向你求助,作为一名 ...
- js读取cookie 根据cookie名称获取值、赋值
借鉴:原作者https://blog.csdn.net/zouxuhang/article/details/80548417 //方法1 //存在问题:如果cookie中存在 aaaname= ...
- Python--day72--Cookie和Session内容回顾
1. Cookie是什么 保存在浏览器端的键值对 为什么要有Cookie? 因为HTTP请求是无状态的 Cookie的原理? 服务端可以在返回响应的时候 做手脚 在浏览器上写入键值对(Cookie) ...
- iptables端口映射
见上节透明代理设置 #iptables -t nat -A PREROUTING -i eth0 -p tcp -s 192.168.62.0/24 --dport 80 -j REDIRECT -- ...
- java Jre和Jdk的区别?
JRE:(Java Runtime Environment),java运行环境.包括Java虚拟机(JVM Java Virtual Machine)和Java程序所需的核心类库等,如果想要运行一个开 ...