1. 程式人生 > >Popular Cows(POJ 2186)

Popular Cows(POJ 2186)

n) pre const pair lines 排序 tro cit ever

  • 原題如下: Popular Cows
    Time Limit: 2000MS Memory Limit: 65536K
    Total Submissions: 40746 Accepted: 16574

    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

    3 3
    1 2
    2 1
    2 3
    

    Sample Output

    1
    

    Hint

    Cow 3 is the only cow of high popularity.
  • 題解:建圖顯然,假設兩頭牛A和B都被其他所有牛認為是紅人,那麽顯然A和B互相認為對方是紅人,即存在一個包含A、B兩個頂點的圈,或者說,A、B同屬於一個強連通分量,反之,如果一頭牛被其他所有牛認為是紅人,那麽其所屬的強連通分量內的所有牛都被其他所有牛認為是紅人。由此可知,把圖進行強連通分量分解後,至多有一個強連通分量滿足題目的條件。而進行強連通分解時,我們還可以得到各個強連通分量拓撲排序後的順序,唯一可能成為解的只有拓撲序最後的強連通分量,,所以在最後,我們只要檢查最後一個強連通分量是否從所有頂點可達就好了。該算法的復雜度為O(N+M)。
  • 代碼:
     1 #include <cstdio>
     2
    #include <stack> 3 #include <vector> 4 #include <algorithm> 5 #include <cstring> 6 7 using namespace std; 8 9 stack<int> s; 10 const int MAX_V=11000; 11 bool instack[MAX_V]; 12 int dfn[MAX_V]; 13 int low[MAX_V]; 14 int ComponentNumber=0; 15 int index; 16 vector<int> edge[MAX_V]; 17 vector<int> redge[MAX_V]; 18 vector<int> Component[MAX_V]; 19 int inComponent[MAX_V]; 20 int N, M; 21 bool visited[MAX_V]; 22 23 void add_edge(int x, int y) 24 { 25 edge[x].push_back(y); 26 redge[y].push_back(x); 27 } 28 29 void tarjan(int i) 30 { 31 dfn[i]=low[i]=index++; 32 instack[i]=true; 33 s.push(i); 34 int j; 35 for (int e=0; e<edge[i].size(); e++) 36 { 37 j=edge[i][e]; 38 if (dfn[j]==-1) 39 { 40 tarjan(j); 41 low[i]=min(low[i], low[j]); 42 } 43 else 44 if (instack[j]) low[i]=min(low[i], dfn[j]); 45 } 46 if (dfn[i]==low[i]) 47 { 48 ComponentNumber++; 49 do 50 { 51 j=s.top(); 52 s.pop(); 53 instack[j]=false; 54 Component[ComponentNumber].push_back(j); 55 inComponent[j]=ComponentNumber; 56 } 57 while (j!=i); 58 } 59 } 60 61 void rdfs(int v) 62 { 63 visited[v]=true; 64 for (int i=0; i<redge[v].size(); i++) 65 { 66 if (!visited[redge[v][i]]) 67 { 68 rdfs(redge[v][i]); 69 } 70 } 71 } 72 73 int main() 74 { 75 memset(dfn, -1, sizeof(dfn)); 76 scanf("%d %d", &N, &M); 77 for (int i=0; i<M; i++) 78 { 79 int x, y; 80 scanf("%d %d", &x, &y); 81 add_edge(x, y); 82 } 83 for (int i=1; i<N+1; i++) 84 { 85 if (dfn[i]==-1) tarjan(i); 86 } 87 int v=Component[1][0]; 88 int num=Component[1].size(); 89 rdfs(v); 90 for (int i=1; i<=N; i++) 91 { 92 if (!visited[i]) 93 { 94 num=0; 95 break; 96 } 97 } 98 printf("%d\n", num); 99 }

Popular Cows(POJ 2186)