内 限制:64MB 时间限制:1000ms
现在给你n个物种和m条能量流动关系,求其中的食物链条数。
物种的名称为从1到n的编号。
m 条能量流动关系形如
a1 b1
a2 b2
a3 b3
… …
am−1 bm−1
am bm
其中 ai bi表示能量从物种ai流向物种bi。
注意单独的一种孤立生物不算一条食物链。
输入描述:
多组数据每组第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(保证输入数据符合生物学特点,且不会有重复的能量流动关系出现)
输出描述:
每组一个整数一行,即食物网中的食物链条数。
样例输入:
复制
10 161 21 41 102 32 54 34 54 86 57 67 98 59 810 610 710 9
样例输出:
9
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
using namespace std;
const int maxn = 1e5 + 10;
int A[maxn],B[maxn];
int r[maxn],c[maxn],tot[maxn];
queue<int >q;
vector<int >vt[maxn];
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(r,0,sizeof(r));
memset(c,0,sizeof(c));
memset(tot,0,sizeof(tot));
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
vt[x].push_back(y);
r[y]++;c[x]++;
}
for(int i=1;i<n;i++)
{
if(c[i]&&!r[i])
{
tot[i]=1;
q.push(i);
}
}
while(!q.empty())
{
int k=q.front();
q.pop();
for(int i=0;i<vt[k].size();i++)
{
int to=vt[k][i];
tot[to]+=tot[k];
r[to]--;
if(!r[to])q.push(to);
}
}
int ans=0;
for(int i=1;i<=n;i++)
if(!c[i])ans+=tot[i];
printf("%d\n",ans);
}
return 0;
}
内存限制:64MB
时间限制:1000ms
Special Judge: No
accepted:6
submit:
拓扑排序的思想虽然不寻常,但是却很简单,有两个必要的步骤:
1. 找到一个没有后继的顶点;
2.从图中删除这个顶点,在列表中插入顶点的标记
然后重复1和2,直到所有顶点都从图中删除,这时候列表显示的顶点顺序就是拓扑排序的结果了。
但是我们需要考虑一种特殊的有向图:环。即A->B->C->D->A。这种必然会导致找不着“没有后继的节点”,这样便无法使用拓扑排序了。
内存限制:64MB
时间限制:1000ms
Special Judge: No
题目描述:
现在给你n个物种和m条能量流动关系,求其中的食物链条数。
物种的名称为从1到n的编号。
m 条能量流动关系形如
a1 b1
a2 b2
a3 b3
… …
am−1 bm−1
am bm
其中 ai bi表示能量从物种ai流向物种bi。
注意单独的一种孤立生物不算一条食物链。
输入描述:
多组数据 每组第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(保证输入数据符合生物学特点,且不会有重复的能量流动关系出现)
输出描述:
每组一个整数一行,即食物网中的食物链条数。
样例输入:
复制
10 16 1 2 1 4 1 10 2 3 2 5 4 3 4 5 4 8 6 5 7 6 7 9 8 5 9 8 10 6 10 7 10 9
样例输出:
9