P3183 [HAOI2016]食物链

题目描述

如图所示为某生态系统的食物网示意图,据图回答第1小题现在给你n个物种和m条能量流动关系,求其中的食物链条数。物种的名称为从1到n编号M条能量流动关系形如a1 b1a2 b2a3 b3......am-1 bm-1am bm其中ai bi表示能量从物种ai流向物种bi,注意单独的一种孤立生物不算一条食物链

输入输出格式

输入格式:

 

第一行两个整数n和m,接下来m行每行两个整数ai bi描述m条能量流动关系。(数据保证输入数据符号生物学特点,且不会有重复的能量流动关系出现)1<=N<=100000 0<=m<=200000题目保证答案不会爆 int

 

输出格式:

 

一个整数即食物网中的食物链条数

 

输入输出样例

输入样例#1:
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

题目标签写的是动态规划,但是自己yy了一种拓扑排序+出入度统计的做法,第一遍交居然A了,,
做法很简单,
记两个入度数组,一个用作拓扑排序,一个用作判断答案,然后记一个出度,
拓扑排序
最后特判一下加个和就好

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<cmath>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int MAXN=400001;
 8 inline void read(int &n)
 9 {
10     char c=getchar();n=0;bool flag=0;
11     while(c<'0'||c>'9')    c=='-'?flag=1,c=getchar():c=getchar();
12     while(c>='0'&&c<='9')    n=n*10+c-48,c=getchar();flag==1?n=-n:n=n;
13 }
14 struct node
15 {
16     int u,v,w,nxt;
17 }edge[MAXN];
18 int head[MAXN];
19 int num=1;
20 int dp[MAXN];
21 int chudu[MAXN];
22 int rudu2[MAXN];
23 inline void add_edge(int x,int y,int z)
24 {
25     edge[num].u=x;
26     edge[num].v=y;
27     edge[num].w=z;
28     edge[num].nxt=head[x];
29     head[x]=num++;
30 }
31 int rudu[MAXN];
32 int n,m;
33 void Topsort()
34 {
35     queue<int>q;
36     int tot=0;
37     for(int i=1;i<=n;i++)
38         if(!rudu[i])    q.push(i),tot++;
39     while(q.size()!=0)
40     {
41         int p=q.front();
42         q.pop();
43         for(int i=head[p];i!=-1;i=edge[i].nxt)
44         {
45             dp[edge[i].v]+=dp[p];
46             rudu[edge[i].v]--;
47             if(!rudu[edge[i].v]    )    q.push(edge[i].v);
48         }
49     }
50 }
51 int main()
52 {
53     memset(head,-1,sizeof(head));
54     read(n);read(m);
55     for(int i=1;i<=m;i++)
56     {
57         int a,b;read(a);read(b);
58         add_edge(a,b,1);
59         rudu[b]++;
60         rudu2[b]++;
61         chudu[a]++;
62     }
63     for(int i=1;i<=n;i++)
64         if(!rudu[i])    dp[i]=1;
65     Topsort();
66     int ans=0;
67     for(int i=1;i<=n;i++)
68         if(chudu[i]==0&&rudu2[i]!=0)
69             ans+=dp[i];
70     printf("%d",ans);
71     return 0;
72 }

 

 
posted @ 2017-09-23 08:28  自为风月马前卒  阅读(274)  评论(0编辑  收藏  举报

Contact with me