【动态规划1】动态规划的引入 P4017 最大食物链计数 拓扑排序(需要有图的基础)+计数问题

【动态规划1】动态规划的引入 P4017 最大食物链计数  拓扑排序

【动态规划1】动态规划的引入

该题是有向图。

样例数据模拟如下所示,可结合AC代码进行阅读:

状态转移方程:

f[v]=(f[v]+f[u])%mod;

该题难点在于:存在多个 最左端,存在多个 最右端.

故应输出多个 最右端 的和。

AC代码如下:

#include <bits/stdc++.h>
#define mod 80112002
#define maxn 5010
#define maxm 500010
int n,m,head[maxn],tot,rd[maxn],cd[maxn],f[maxn];//rd[]入度,cd[]出度 
int q[maxn],h,t;
struct node{
	int to,next;
}e[maxm];
void add_edge(int u,int v){//邻接表 
	tot++,e[tot].to=v,e[tot].next=head[u],head[u]=tot;
}
void topsort(){//拓扑排序 
	int u,v,b;
	h=t=1;
	for(u=1;u<=n;u++)//存在多个最左端 
		if(!rd[u])f[u]=1,q[t]=u,t++;
	while(h<t){
		u=q[h];
		for(b=head[u];b;b=e[b].next){
			v=e[b].to;
			rd[v]--;
			f[v]=(f[v]+f[u])%mod;
			if(!rd[v])q[t]=v,t++;
		}
		h++;
	}
}
int main(){
	int i,u,v,b,sum=0;
	scanf("%d%d",&n,&m);
	for(i=1;i<=m;i++){
		scanf("%d%d",&u,&v);
		add_edge(u,v);
		rd[v]++,cd[u]++;
	}
	topsort();
	for(i=1;i<=n;i++)//存在多个最右端 
		if(!cd[i])sum=(sum+f[i])%mod;
	printf("%d\n",sum);
	return 0;
} 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章