1. 程式人生 > >Popular Cows poj2186

Popular Cows poj2186

Popular Cows
Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 33277 Accepted: 13559

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. 

Source

題目描述:
  有n只牛,牛之間存在一些關係,比如a認為b很受歡迎,b認為c很受歡迎,這樣呢,a也會認為c很受歡迎,問根據給出的關係,有多少頭牛被其他所有的牛都認為是受歡迎的?

解題思路:

        對於一個有向無環圖來說,其中有且僅有一個點出度為零,那麼這個特殊的點,可以由其他任何點到達。那麼接下來我們直接對所給的圖進行強連通分量劃分,然後把每個強連通分量看做一個點,判定出度為零的點有幾個,如果有一個就輸出這個點對應的強連通分量含有的節點個數,否則為零。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <string>
#include <cmath>
#include <cctype>
#include <ctime>
#include <queue>
using namespace std;

int n,m,s=0,top=0,index=0;
int first[10001],zhan[10001];
int low[10001],num[10001];
bool dian[10001];
struct tarjan{int x,y,next;};
tarjan bian[100001];

int sum=0,father[10001]={0},maxx=0,p,ans=0,visit[10001];

void build(int x,int y)
{
   s++;
   bian[s].next=first[x];
   first[x]=s;
   bian[s].x=x;
   bian[s].y=y;
}

void dfs(int x)
{
   index++;
   low[x]=index;
   num[x]=index;
   top++;
   zhan[top]=x;
   dian[x]=true;

   int k,i;
   k=first[x];
   while(k!=-1)
   {
   	 if(num[bian[k].y]==0)
   	 {
   	   dfs(bian[k].y);
   	   low[x]=min(low[x],low[bian[k].y]);
   	 }
   	 else if(bian[k].y) low[x]=min(low[x],num[bian[k].y]);
   	 k=bian[k].next;
   }

   if(low[x]==num[x])
   {
   	 sum++;
   	 i=zhan[top];
   	 while(i!=x)
   	 {
   	   dian[i]=false;
   	   father[i]=sum;
   	   top--;
   	   i=zhan[top];
   	 }
   	 dian[i]=false;
   	 father[i]=sum;
   	 top--;
   }
}

int main()
{
   //freopen("lx.in","r",stdin);
   //freopen("lx.out","w",stdout);
   memset(first,-1,sizeof(first));
   memset(zhan,0,sizeof(zhan));
   memset(low,0,sizeof(low));
   memset(num,0,sizeof(num));
   memset(dian,false,sizeof(dian));
   memset(bian,0,sizeof(bian));
   memset(visit,0,sizeof(visit));

   scanf("%d%d",&n,&m);
   for(int i=1;i<=m;i++)
   {
   	 int x,y;
   	 scanf("%d%d",&x,&y);
   	 build(x,y);
   }

   for(int i=1;i<=n;i++) if(num[i]==0) dfs(i);

   for(int i=1;i<=n;i++)
     for(int j=first[i];j!=-1;j=bian[j].next)
       if(father[i]!=father[bian[j].y]) visit[father[i]]++;

   for(int i=1;i<=sum;i++)
   	 if(visit[i]==0)
   	 {
   	   p=i;
   	   maxx++;
   	 }

   if(maxx==1)
   {
   	 ans=0;
   	 for(int i=1;i<=n;i++)
   	   if(father[i]==p) ans++;
   	 cout<<ans<<endl;
   }
   else cout<<"0"<<endl;

   return 0;
}

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