【连通图|强连通+缩点】POJ-2186 Popular Cows
2014-12-27 15:43
411 查看
Popular Cows
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
Sample Output
Hint
Cow 3 is the only cow of high popularity.
————————————————————————————————————————————————————————————————————————————————————————————————
题意:N个奶牛有M对仰慕关系,给出u、v表示u仰慕v,问有几头奶牛受到其余所有奶牛的仰慕。(仰慕关系具有传递性)
思路:每个强连通分量当中,结点两两可达,也就是说每个奶牛相互仰慕。这就是一个朋友圈。给每个朋友圈编号,将它们缩成一个点。缩点之后,就得到了若干个朋友圈。每个朋友圈就是一个强连通分量。
如果朋友圈a到朋友圈b之间有边,那么朋友圈a里面的所有奶牛都仰慕朋友圈b。
这个时候看这些点的出度。出度为0的点就是被所有奶牛仰慕的点。
但是如果出度为0的点超过1个,说明没有任何一个奶牛被所有其他奶牛仰慕。
代码如下:
Time Limit: 2000MS | Memory Limit: 65536K | |
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.
————————————————————————————————————————————————————————————————————————————————————————————————
题意:N个奶牛有M对仰慕关系,给出u、v表示u仰慕v,问有几头奶牛受到其余所有奶牛的仰慕。(仰慕关系具有传递性)
思路:每个强连通分量当中,结点两两可达,也就是说每个奶牛相互仰慕。这就是一个朋友圈。给每个朋友圈编号,将它们缩成一个点。缩点之后,就得到了若干个朋友圈。每个朋友圈就是一个强连通分量。
如果朋友圈a到朋友圈b之间有边,那么朋友圈a里面的所有奶牛都仰慕朋友圈b。
这个时候看这些点的出度。出度为0的点就是被所有奶牛仰慕的点。
但是如果出度为0的点超过1个,说明没有任何一个奶牛被所有其他奶牛仰慕。
代码如下:
#include <cstdio> #include <cstdlib> #include <cstring> #include <stack> #define Mem(f, x) memset(f, x, sizeof(f)) #define PB push_back using namespace std; const int N = 1e4+5, M = 5e4+5;; int dfn , scc_id , head , out , line[M][2]; int deep, scc_cnt, tot, n, m; stack <int> s; struct Edge { int v, next; Edge(){} Edge(int _v, int _next): v(_v), next(_next){} }e[M]; void __init__() { for(int i = 0; i < n; i++) { out[i] = dfn[i] = scc_id[i] = 0; head[i] = -1; } tot = deep = scc_cnt = 0; } void add(int u, int v) { e[tot] = Edge(v, head[u]); head[u] = tot++; } int dfs(int u) { int lowu = dfn[u] = ++deep; s.push(u); for(int i = head[u]; ~i; i = e[i].next) { int v = e[i].v; if(!dfn[v]) { int lowv = dfs(v); lowu = min(lowu, lowv); } else if(!scc_id[v]) { lowu = min(lowu, dfn[v]); } } if(lowu == dfn[u]) { scc_cnt++; while(1) { int x = s.top(); s.pop(); scc_id[x] = scc_cnt; if(x == u) break; } } return lowu; } int main() { #ifdef J_Sure freopen("000.in", "r", stdin); //freopen("999.out", "w", stdout); #endif while(~scanf("%d%d", &n, &m)) { __init__(); for(int i = 0; i < m; i++) { int u, v; scanf("%d%d", &u, &v); u--; v--; line[i][0] = u; line[i][1] = v; add(u, v); } for(int i = 0; i < n; i++) { if(!dfn[i]) dfs(i); } //缩点:把scc_id所储存的强连通分量标号当作顶点 for(int i = 0; i < m; i++) { int u = scc_id[line[i][0]], v = scc_id[line[i][1]]; if(u != v) out[u]++; } //统计出度为0的点,多于1个说明不只一头牛是终点 int god = 0, who; for(int i = 1; i <= scc_cnt; i++) { if(!out[i]) { god++; if(god > 1) break; who = i; } } int ans = 0; if(god == 1) { for(int i = 0; i < n; i++) { if(scc_id[i] == who) ans++; } printf("%d\n", ans); } else puts("0"); } return 0; }
相关文章推荐
- POJ 2186 Popular Cows(强连通分量缩点,Tarjan算法)
- POJ-2186 Popular Cows 强连通 + 缩点
- poj 2186 Popular Cows 有向图强连通分量 tarjan
- POJ 2186 Popular Cows (强连通 出度)
- poj 2186 Popular Cows 有向图强连通分量 tarjan
- [poj 2186]Popular Cows[Tarjan强连通分量]
- POJ 2186-Popular Cows:强连通分量问题
- POJ 2186-Popular Cows:强连通分量问题
- poj2186--Popular Cows(强连通+缩点)
- poj 2186 Popular Cows 强连通
- POJ 2186 -- Popular Cows【强连通分支 && Tarjan缩点】
- 【Kosaraju && 连通分量】POJ - 2186 Popular Cows
- POJ 2186 Popular Cows(tarjan求强连通)
- 有向图强连通分量-poj-2186-Popular Cows
- 强连通分量分解 Kosaraju算法 (poj 2186 Popular Cows)
- poj 2186 Popular Cows(Tarjan,强连通分量缩点)
- poj 2186 Popular Cows(第一道强连通分支题)
- POJ 2186 Popular Cows【强连通】
- POJ 2186 Popular Cows(强连通,kosaraju算法)
- POj 2186 Popular Cows[连通分量]