1051: [HAOI2006]受欢迎的牛
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 5537 Solved: 2940
[ Submit][ Status][ Discuss]
Description
Input
Output
一个数,即有多少头牛被所有的牛认为是受欢迎的。
Sample Input
1 2
2 1
2 3
Sample Output
HINT
Source
强连通模板题 ->自己整理的tarjan模板
会强连通的话,很容易想到,牛A喜欢牛B的话,呢就在他们之间建一条有向边,
若当前的牛被其他所有牛喜欢的话,则当前牛所在的强连通分量出度必为0,很容易证明的
反之,若存在大于1个强连通分量的出度为0,则一定不存在有牛被其他所有牛喜欢
#include<stack>
#include<vector>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
#define maxn 1000005
stack<int>s;
vector<int>q[maxn],p[maxn];
int dfn[maxn],low[maxn],t,cnt,vis[maxn],in[maxn],num,ans[maxn],belong[maxn];
void tarjan(int u)
{
int i,now;
dfn[u]=low[u]=++t;
s.push(u);in[u]=1;vis[u]=1;
for(i=0;i<q[u].size();i++)
{
int v=q[u][i];
if(vis[v]==0)
{
tarjan(v);
low[u]=min(low[u],low[v]);
continue;
}
if(in[v])
low[u]=min(low[u],dfn[v]);
}
if(dfn[u]==low[u])
{
num++;
int sum=0;
while(s.empty()==0)
{
sum++;
now=s.top();
s.pop();
in[u]=0;
belong[now]=num;
if(now==u)
break;
}
ans[num]=sum;
}
}
int main(void)
{
int i,j,x,y,n,m;
scanf("%d%d",&n,&m);
for(i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
q[x].push_back(y);
}
for(i=1;i<=n;i++)
if(vis[i]==0)
tarjan(i);
for(i=1;i<=n;i++)
for(j=0;j<q[i].size();j++)
{
int v=q[i][j];
if(belong[i]!=belong[v])
p[belong[i]].push_back(belong[v]);
}
int sum=0,anss=0;
for(i=1;i<=num;i++)
if(p[i].size()==0)
sum++,anss=ans[i];
if(sum==1)
printf("%d\n",anss);
else
printf("0\n");
return 0;
}