zoukankan      html  css  js  c++  java
  • Poj 2186 Popular Cows

    http://poj.org/problem?id=2186

    题意:给定N头牛和M个有序对(A,B)。每头牛都想成为牛群中的popular。(A,B)表示牛A认为牛B是popular。且关系具有传递性,eg:如果A认为B是popular,B认为C是popular,则A认为C是popular。求被其他所有牛认为是popular牛的总数。

    题解:是一道典型求强连通分量的题。把图进行强连通分量分解后,至多有一个强连通分量满足题目的条件。得到各个强连通分量拓扑排序后的顺序,唯一可能成为解的只有拓扑排序后的强连通分量。所以只需检查这个强连通分量是否可以从所有顶点到达即可。(求强连通分量用的不是大多数人用的tarjan……而是Kosaraju。Kosaraju与tarjan区别在于Kosaraju需要建立逆图,进行两次DFS。

    补充:详细tarjan介绍:http://blog.csdn.net/wsniyufang/article/details/6604458

      1 //
      2 //  main.cpp
      3 //  POJ 2186
      4 //
      5 //  Created by zhang on 14-4-9.
      6 //  Copyright (c) 2014年 apple. All rights reserved.
      7 //
      8 
      9 #include <iostream>
     10 #include <cstring>
     11 #include <cstdio>
     12 #include <cstdlib>
     13 #include <cmath>
     14 #include <string>
     15 #include <vector>
     16 #include <list>
     17 #include <map>
     18 #include <queue>
     19 #include <stack>
     20 #include <bitset>
     21 #include <algorithm>
     22 #include <numeric>
     23 #include <functional>
     24 #include <set>
     25 #include <fstream>
     26 
     27 using namespace std;
     28 
     29 const int maxn=50010;
     30 int A[maxn],B[maxn];
     31 int V;
     32 vector<int> G[maxn];
     33 vector<int> rG[maxn];
     34 vector<int> vs;
     35 bool used [maxn];
     36 int cmp[maxn];//所属强连通分量的拓扑序
     37 int N,M;
     38 void add_edge(int from,int to)
     39 {
     40     G[from].push_back(to);
     41     rG[to].push_back(from);
     42 }
     43 
     44 void dfs(int v)
     45 {
     46     used[v]=true;
     47     for (int i=0; i<G[v].size(); i++) {
     48         if (!used[G[v][i]]) {
     49             dfs(G[v][i]);
     50         }
     51     }
     52     vs.push_back(v);
     53 }
     54 
     55 void rdfs(int v,int k)
     56 {
     57     used[v]=true;
     58     cmp[v]=k;
     59     for (int i=0; i<rG[v].size(); i++) {
     60         if (!used[rG[v][i]]) {
     61             rdfs(rG[v][i], k);
     62         }
     63     }
     64 }
     65 
     66 int scc()
     67 {
     68     memset(used, 0, sizeof(used));
     69     vs.clear();
     70     for (int v=0; v<V; v++) {
     71         if (!used[v]) {
     72             dfs(v);
     73         }
     74     }
     75     memset(used, 0, sizeof(used));
     76     int k=0;
     77     for (int i=vs.size()-1; i>=0; i--) {
     78         if (!used[vs[i]]) {
     79             rdfs(vs[i], k++);
     80         }
     81     }
     82     return k;
     83 }
     84 
     85 //void solve()
     86 //{
     87 
     88 //}
     89 int main()
     90 {
     91     scanf("%d%d",&N,&M);
     92     for (int i=0; i<M; i++) {
     93         scanf("%d%d",&A[i],&B[i]);
     94         add_edge(A[i]-1, B[i]-1);
     95     }
     96     V=N;
     97     int n=scc();
     98     int u=0,num=0;
     99     for (int v=0; v<V; v++) {
    100         if (cmp[v]==n-1) {
    101             u=v;
    102             num++;
    103         }
    104     }
    105     memset(used, 0, sizeof(used));
    106     rdfs(u, 0);
    107     for (int v=0; v<V; v++) {
    108         if (!used[v]) {
    109             num=0;
    110             break;
    111         }
    112     }
    113     
    114     printf("%d
    ",num);
    115 
    116     return 0;
    117 }
  • 相关阅读:
    Codeforces Round 546 (Div. 2)
    Codeforces Round 545 (Div. 2)
    Codeforces Round 544(Div. 3)
    牛客小白月赛12
    Codeforces Round 261(Div. 2)
    Codeforces Round 260(Div. 2)
    Codeforces Round 259(Div. 2)
    Codeforces Round 258(Div. 2)
    Codeforces Round 257 (Div. 2)
    《A First Course in Probability》-chaper5-连续型随机变量-随机变量函数的分布
  • 原文地址:https://www.cnblogs.com/der-z/p/3654974.html
Copyright © 2011-2022 走看看