【動態規劃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;
} 

 

 

 

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