【動態規劃1】動態規劃的引入 P4017 最大食物鏈計數 拓撲排序
該題是有向圖。
樣例數據模擬如下所示,可結合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;
}