zoukankan      html  css  js  c++  java
  • poj 2186 (强连通分支)

    题意:每头牛都想成为牛群中的红人。给N头牛的的牛群和M个有序对(A,B)。(A,B)表示牛A认为B是红人。该关系具有传递性,所以如果牛A认为B是红人,牛B认为牛C是红人,那么牛A也认为牛C是红人。不过,给定的有序对中可能包含(A,B)和(B,C),但不包含(A,C)。求被其他牛认为是红人的总数。

    思路:方法是是找到拓扑排序最后的那个强连通分量在统计他是不是能访问到所有的结点就OK了。

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cmath>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <queue>
     8 #include <stack>
     9 #include <vector>
    10 #define MP(a, b) make_pair(a, b)
    11 #define PB(a) push_back(a)
    12 
    13 using namespace std;
    14 
    15 typedef long long ll;
    16 typedef pair<int ,int> pii;
    17 typedef pair<unsigned int, unsigned int> puu;
    18 typedef pair<int ,double> pid;
    19 typedef pair<ll, int> pli;
    20 
    21 const int INF = 0x3f3f3f3f;
    22 const double eps = 1e-6;
    23 const int LEN = 10000+10;
    24 int vis[LEN], n, m, cmp[LEN];
    25 vector<int> Map[LEN], rMap[LEN], vs;
    26 
    27 void dfs(int v)
    28 {
    29     vis[v] = 1;
    30     for(int i=0; i<Map[v].size(); i++){
    31         if(!vis[Map[v][i]])dfs(Map[v][i]);
    32     }
    33     vs.PB(v);
    34 }
    35 
    36 void rdfs(int v, int k)
    37 {
    38     vis[v] = 1;
    39     cmp[v] = k;
    40     for(int i=0; i<rMap[v].size(); i++){
    41         if(!vis[rMap[v][i]])rdfs(rMap[v][i], k);
    42     }
    43 }
    44 
    45 int scc()
    46 {
    47     memset(vis, 0, sizeof vis);
    48     vs.clear();
    49     for(int i=1; i<=n; i++){
    50         if(!vis[i])dfs(i);
    51     }
    52     memset(vis, 0, sizeof vis);
    53     int k = 0;
    54     for(int i=vs.size()-1; i>=0; i--){
    55         if(!vis[vs[i]])rdfs(vs[i], k++);
    56     }
    57     return k;
    58 }
    59 
    60 int main()
    61 {
    62 //    freopen("in.txt", "r", stdin);
    63 
    64     int a, b;
    65     while(scanf("%d%d", &n, &m)!=EOF){
    66         for(int i=0; i<LEN; i++)Map[i].clear();
    67         for(int i=0; i<LEN; i++)rMap[i].clear();
    68         for(int i=0; i<m; i++){
    69             scanf("%d%d", &a, &b);
    70             Map[a].PB(b);
    71             rMap[b].PB(a);
    72         }
    73         int num = scc(), ans = 0, u = 0;
    74         for(int i=1; i<=n; i++)if(cmp[i] == num-1){u = i;ans++;}
    75         memset(vis, 0, sizeof vis);
    76         rdfs(u, 0);
    77         for(int i=1; i<=n; i++)if(!vis[i])ans = 0;
    78         printf("%d
    ", ans);
    79     }
    80     return 0;
    81 }
    View Code
    奔跑吧!少年!趁着你还年轻
  • 相关阅读:
    字符串操作函数5!!
    字符串操作函数4
    字符串操作函数3
    java开发命名规范总结
    centerOS网络NAT和桥接
    input框的内容变化监听
    Xunsearch迅搜项目实战经验
    PHP网络爬虫之CURL学习
    Xunsearch的使用总结
    Xshell 5 过期
  • 原文地址:https://www.cnblogs.com/shu-xiaohao/p/3525857.html
Copyright © 2011-2022 走看看