您的位置:首页 > 其它

1051: [HAOI2006]受欢迎的牛

2015-10-24 20:30 232 查看

1051: [HAOI2006]受欢迎的牛

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 3167  Solved: 1659

[Submit][Status][Discuss]

Description

每一头牛的愿望就是变成一头最受欢迎的牛。现在有N头牛,给你M对整数(A,B),表示牛A认为牛B受欢迎。 这种关系是具有传递性的,如果A认为B受欢迎,B认为C受欢迎,那么牛A也认为牛C受欢迎。你的任务是求出有多少头牛被所有的牛认为是受欢迎的。

Input

第一行两个数N,M。 接下来M行,每行两个数A,B,意思是A认为B是受欢迎的(给出的信息有可能重复,即有可能出现多个A,B)

Output

一个数,即有多少头牛被所有的牛认为是受欢迎的。

Sample Input

3 3

1 2

2 1

2 3

Sample Output

1

HINT

100%的数据N<=10000,M<=50000

Source

连通块缩点。。然后显然出度为0的点都有可能是超级屌的牛,但是如果点数>1就不存在了。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<stack>
#include<vector>
#include<cstring>
using namespace std;

const int maxn = 1e4 + 10;

int pre[maxn],low[maxn],sccno[maxn],out[maxn],p[maxn],Size[maxn],cur = 0,t = 0;
int n,m,i,j;

vector <int> v[maxn];
stack <int> s;

void dfs(int k)
{
pre[k] = low[k] = ++t;
s.push(k);
for (int l = 0; l < v[k].size(); l++)
{
int to = v[k][l];
if (pre[to] == -1) dfs(to),low[k] = min(low[to],low[k]);
else
{
if (sccno[to] == -1) low[k] = min(low[k],low[to]);
}
}
if (low[k] == pre[k])
{
int ss = 0; cur++;
while (1)
{
int S = s.top(); ++ss;
s.pop();
sccno[S] = cur;
if (S == k) break;
}
Size[cur] = ss;
}
}

int main()
{
#ifdef YZY
freopen("yzy.txt","r",stdin);
#endif

cin >> n >> m;
while (m--)
{
int x,y;
scanf("%d%d",&x,&y);
v[x].push_back(y);
}

memset(pre,-1,sizeof(pre));
memset(sccno,-1,sizeof(sccno));
for (i = 1; i <= n; i++)
if (pre[i] == -1) dfs(i);

for (i = 1; i <= n; i++)
for (int l = 0; l < v[i].size(); l++)
{
int to = v[i][l];
if (sccno[to] == sccno[i]) continue;
++out[sccno[i]];
}

int tot = 0,ans = 0;
for (i = 1; i <= cur; i++)
if (!out[i])
{
++tot;
ans += Size[i];
}

if (tot == 1) cout << ans;
else cout << 0;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: