POJ 2186 Superstar Cow

#include <stdio.h>

#define MAX_COWS 10001
#define MAX_PAIRS 50001

int numOfCows;
int numOfPairs;

typedef struct {
  int adjaVertex;
  int nextEdgeNum;
} edge;
int numOfEdges;
edge edgeArray[MAX_PAIRS];
int edgeNumAddedLastly[MAX_COWS];

int time;
int nodeTime[MAX_COWS];
int rootTime[MAX_COWS];
int nodeStack[MAX_COWS];
int inStack[MAX_COWS];
int top;

int SCCNumArray[MAX_COWS];//strong connect component
int numOfSCCs;

int outDegreeOfSCCArray[MAX_COWS];
int numOfSCCsNoOutDeg;
int SCCNumNoOutDeg;

void addEdge(int head, int adjaVertex){
   numOfEdges++;
   int edgeNum = numOfEdges;
   edgeArray[edgeNum].adjaVertex = adjaVertex;
   edgeArray[edgeNum].nextEdgeNum = edgeNumAddedLastly[head];
   edgeNumAddedLastly[head] = edgeNum;
}

void getSCCs(int head){
    time++;
    nodeTime[head] = time;
    rootTime[head] = time;
    top++;
    nodeStack[top] = head;
    inStack[head] = 1;

    int indexOfEdge;
    // Consider successors of head
    for (indexOfEdge = edgeNumAddedLastly[head]; indexOfEdge != 0; indexOfEdge = edgeArray[indexOfEdge].nextEdgeNum){
        int adjaVertax = edgeArray[indexOfEdge].adjaVertex;
        if (nodeTime[ adjaVertax ] == 0){
            //recursively
            getSCCs(adjaVertax);
            //back track
            if (rootTime[adjaVertax] < rootTime[head]){
                rootTime[head] = rootTime[adjaVertax];
            }
        } else {
            if (inStack[adjaVertax] == 1 && nodeTime[adjaVertax] < rootTime[head]){
                //why can not be "rootTime[head] = rootTime[adjaVertax]"
                //adjaVertax is circle root ?
                rootTime[head] = nodeTime[adjaVertax];
            }
        }
    }
    // If head is a root node, pop the stack and generate an SCC
    if (nodeTime[head] == rootTime[head]){
        numOfSCCs++;
        int node;
        do {
            node = nodeStack[top];
            inStack[node] = 0;
            top--;
            SCCNumArray[node] = numOfSCCs;
        } while (top > 0 && node != head);
    }
}

int main()
{
   // freopen("input.txt", "r", stdin);
    /* input */
    scanf("%d %d", &numOfCows, &numOfPairs);
    int head;
    int adjaVertex;
    int indexOfpair;
    for (indexOfpair = 1; indexOfpair <= numOfPairs; indexOfpair++){
        scanf("%d %d", &head, &adjaVertex);
        addEdge(head, adjaVertex);
    }
    /* main */
    //Tarjan
    for (head = 1; head <= numOfCows; head++){
        if (nodeTime[head] == 0){
           getSCCs(head);
        }
    }
    //calculate out degree of every SCC
    for (head = 1; head <= numOfCows; head++){
        int indexOfEdge;
        for (indexOfEdge = edgeNumAddedLastly[head]; indexOfEdge != 0; indexOfEdge = edgeArray[indexOfEdge].nextEdgeNum){
            if (SCCNumArray[head] != SCCNumArray[ edgeArray[indexOfEdge].adjaVertex ]){
               outDegreeOfSCCArray[ SCCNumArray[head] ]++;
            }
        }
    }
    //calculate how many SCCs with out degree
    int indexOfSCC;
    for (indexOfSCC = 1; indexOfSCC <= numOfSCCs; indexOfSCC++){
        if (outDegreeOfSCCArray[indexOfSCC] == 0){
            numOfSCCsNoOutDeg++;
            if (numOfSCCsNoOutDeg > 1){
                //no popular cow ,output 0
                printf("0\n");
                return 0;
            }
            SCCNumNoOutDeg = indexOfSCC;
        }
    }
    /* output */
    int numOfPopularCows = 0;
    int node;
    for (node = 1; node <= numOfCows; node++){
        if (SCCNumArray[node] == SCCNumNoOutDeg){
            numOfPopularCows++;
        }
    }
    printf("%d\n", numOfPopularCows);
    return 0;
}

你可能感兴趣的:(poj,COW,2186,Superstar)