POJ 2186 Superstar Cow

来源:互联网 发布:Ubuntu怎么装openwrt 编辑:程序博客网 时间:2024/06/10 02:44
#include <stdio.h>#define MAX_COWS 10001#define MAX_PAIRS 50001int 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 componentint 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;}

0 0