[POJ2186]Popular Cows(强连通分量)

题目链接:http://poj.org/problem?id=2186

给定n个点m条边,求某点使得其他点都有通向它的一条路径,计算这个点集的大小。

强连通分解后求出度为0的连通分量的个数,如果有且仅有一个连通分量出度为1,则统计这个连通分量中点的数目。

遍历所有点的出边指向的点,判断这两个点是否属于同一个连通分量,记录每个连通分量中的点的数目。

  1 #include <algorithm>
  2 #include <iostream>
  3 #include <iomanip>
  4 #include <cstring>
  5 #include <climits>
  6 #include <complex>
  7 #include <fstream>
  8 #include <cassert>
  9 #include <cstdio>
 10 #include <bitset>
 11 #include <vector>
 12 #include <deque>
 13 #include <queue>
 14 #include <stack>
 15 #include <ctime>
 16 #include <set>
 17 #include <map>
 18 #include <cmath>
 19
 20 using namespace std;
 21
 22 const int maxn = 11111;
 23 typedef struct Edge {
 24     int v;
 25     int next;
 26     Edge() { next = -1; }
 27 }Edge;
 28
 29 int head[maxn], ecnt;
 30 Edge edge[55555];
 31 int n, m;
 32
 33 int bcnt, dindex;
 34 int dfn[maxn], low[maxn];
 35 int stk[maxn], top;
 36 int belong[maxn];
 37 bool instk[maxn];
 38 int dig[maxn];
 39
 40 void init() {
 41     memset(edge, 0, sizeof(edge));
 42     memset(head, -1, sizeof(head));
 43     memset(instk, 0, sizeof(instk));
 44     memset(dfn, 0, sizeof(dfn));
 45     memset(low, 0, sizeof(low));
 46     memset(belong, 0, sizeof(belong));
 47     memset(dig, 0, sizeof(dig));
 48     ecnt = top = bcnt = dindex = 0;
 49 }
 50
 51 void adde(int uu, int vv) {
 52     edge[ecnt].v = vv;
 53     edge[ecnt].next = head[uu];
 54     head[uu] = ecnt++;
 55 }
 56
 57 void tarjan(int u) {
 58     int v = u;
 59     dfn[u] = low[u] = ++dindex;
 60     stk[++top] = u;
 61     instk[u] = 1;
 62     for(int i = head[u]; ~i; i=edge[i].next) {
 63         v = edge[i].v;
 64         if(!dfn[v]) {
 65             tarjan(v);
 66             low[u] = min(low[u], low[v]);
 67         }
 68         else if(instk[v] && dfn[v] < low[u]) {
 69             low[u] = dfn[v];
 70         }
 71     }
 72     if(dfn[u] == low[u]) {
 73         bcnt++;
 74         do {
 75             v = stk[top--];
 76             instk[v] = 0;
 77             belong[v] = bcnt;
 78         } while(v != u && top != 0);
 79     }
 80 }
 81
 82 int main() {
 83     // freopen("in", "r", stdin);
 84     int uu, vv;
 85     while(~scanf("%d %d", &n, &m)) {
 86         init();
 87         for(int i = 0; i < m; i++) {
 88             scanf("%d %d", &uu, &vv);
 89             adde(uu, vv);
 90         }
 91         for(int i = 1; i <= n; i++) {
 92             if(!dfn[i]) {
 93                 tarjan(i);
 94             }
 95         }
 96         for(int i = 1; i <= n; i++) {
 97             for(int j = head[i]; ~j; j = edge[j].next) {
 98                 if(belong[i] != belong[edge[j].v]) {
 99                     dig[belong[i]]++;
100                 }
101             }
102         }
103         int tmp, cnt = 0, ans = 0;
104           for(int i = 1; i <= bcnt; i++) {
105               if(!dig[i]) {
106                   cnt++;
107                   tmp = i;
108               }
109         }
110           if(cnt == 1) {
111               for(int i = 1; i <= n; i++) {
112                   if(belong[i] == tmp) {
113                       ans++;
114                   }
115               }
116               printf("%d\n", ans);
117           }
118           else {
119               printf("0\n");
120           }
121     }
122     return 0;
123 }
时间: 2024-10-14 17:05:01

[POJ2186]Popular Cows(强连通分量)的相关文章

poj2186 Popular Cows --- 强连通

给一个有向图,问有多少结点是其他所有结点都可以到达的. 等价于,在一个有向无环图上,找出度为0 的结点,如果出度为0的结点只有一个,那么这个就是答案,如果大于1个,则答案是0. 这题有环,所以先缩点.求唯一出度为0的强连通分量. #include<cstdio> #include<cstring> #include<vector> #include<queue> #include<iostream> #define inf 0x3f3f3f3f

POJ 2186 Popular Cows --强连通分量

题意:给定一个有向图,问有多少个点由任意顶点出发都能达到. 分析:首先,在一个有向无环图中,能被所有点达到点,出度一定是0. 先求出所有的强连通分支,然后把每个强连通分支收缩成一个点,重新建图,这样,这个有向图就变成了一个有向无环图. 在这个新的图中,只需知道出度为0的点有几个即可. 如果出度为0的点超过1个,则输出0:否则输出出度为0的点所代表的那个强连通分支的分量数即可. 用Tarjan求强连通分量 代码: #include <iostream> #include <cstdio&g

POJ 2186 Popular Cows 强连通分量模板

题意 强连通分量,找独立的块 强连通分量裸题 #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorithm> #include <iostream> using namespace std; const int maxn = 50005; int n, m; struct Edge { int v, next;

POJ 2186 - Popular Cows - 强连通分量,缩点

题目大意: 给定一个含N个点.M条边的有向图,求其中有多少个点,可以由其他任意一点出发到达它? N<=1e4,M<=5e4. 为了描述和编程简便,我们建立原图的反图,这样问题转化为:有多少个点满足从它出发可以到达其他任意一点. 若无特殊说明,以下所指的图均为反图. 引理1:满足条件的所有点必然在同一强连通分量内. 证明很简单,如果它们不在同一强连通分量内,那么其中必然有两点x,y使得x→y的路径不存在,与题目要求矛盾. 我们考虑求出该图的所有强连通分量,然后对于每个强连通分量,检验从其中任一点

强连通分量tarjan缩点——POJ2186 Popular Cows

这里的Tarjan是基于DFS,用于求有向图的强联通分量. 运用了一个点dfn时间戳和low的关系巧妙地判断出一个强联通分量,从而实现一次DFS即可求出所有的强联通分量. §有向图中, u可达v不一定意味着v可达u.    相互可达则属于同一个强连通分量    (Strongly Connected Component, SCC) §有向图和它的转置的强连通分量相同 §所有SCC构成一个DAG(有向无环图) dfn[u]为节点u搜索的次序编号(时间戳),即首次访问u的时间 low[u]为u或u的

POJ2186 Popular Cows 【强连通分量Kosaraju】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 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 &l

POJ2186 Popular Cows 【强连通分量】+【Kosaraju】+【Tarjan】+【Garbow】

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 23445   Accepted: 9605 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 &l

POJ2186 Popular Cows【Kosaraju】【强连通分量】

Popular Cows Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 24266Accepted: 9954 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 <= 5

POJ2186 Popular Cows【Tarjan】【强连通分量】

题目连接: http://poj.org/problem?id=2186 题目大意: 每头奶牛都希望自己成为最欢迎的那头牛.给你N头牛,M个崇拜关系(A,B).意思是牛A 崇拜牛B.特别是,如果牛A崇拜牛B,牛B崇拜牛C,那么牛A也崇拜牛C.那么问题来了: 请计算出被所有牛崇拜的牛的个数. 思路: 把崇拜关系(A,B)看做是一条有向边,并且,我们发现牛的崇拜关系具有传递性.那么只要 牛A有一条路径连向牛B,就可以判定牛A崇拜牛B.于是,被所有牛崇拜的牛就是所有的点 都存在一条路径连向它的有向路径

Popular Cows 强连通(kosaraju)

Popular Cows Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 30652   Accepted: 12439 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 &