[题解]洛谷P4017 最大食物链计数
一开始不知道toposort可以做,写了个记忆化搜索,结果T了qwq
然后一看题解,豁然开朗,本蒟蒻见识浅短,还不曾知道还有这种操作
设 f[i] 是以i结尾的最长链个数,那么 f[i]=∑f[k] (k有一条出边指向i)
然后统计出度为0的点i的f[i],累加就是ans
这一过程显然可以在toposort里VAN成
代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<queue> using namespace std; const int MAXN = 5001,MAXM = 500001,MOD = 80112002; typedef long long ll; inline int read(){ int x=0,w=1;char c=getchar(); while(c<'0'||c>'9'){ if(c=='-')w=-1; c=getchar(); } while(c>='0'&&c<='9'){ x=(x<<3)+(x<<1)+c-'0'; c=getchar(); } return x*w; } int n,m,ans=0; int first[MAXN]; struct edge{ int v,next; }e[MAXM]; int tot=0; void insert(int u,int v){ ++tot;e[tot].v=v;e[tot].next=first[u];first[u]=tot; } int f[MAXN],rd[MAXN],cd[MAXN]; queue<int> q; void solve(){ for(register int i=1;i<=n;i++) if(!rd[i]){ q.push(i);f[i]=1; } while(!q.empty()){ int u=q.front();q.pop(); for(int i=first[u];i!=-1;i=e[i].next){ int v=e[i].v; f[v]+=f[u];f[v]%=MOD; if(!--rd[v])q.push(v); } } } int main(){ memset(first,-1,sizeof(first)); n=read();m=read(); for(register int i=1;i<=m;i++){ int x=read(),y=read(); rd[y]++;cd[x]++; insert(x,y); } solve(); for(register int i=1;i<=n;i++) if(!cd[i]){ ans+=f[i];ans%=MOD; } printf("%d",ans%MOD); return 0; }
本篇文章为SHINE_GEEK原创,转载请注明来源!
-------------------------------------
签名:自己选的路,跪着也要走完;理想的实现,需要不懈奋斗!
-------------------------------------
written_by:SHINE_GEEK
blog_addr:www.cnblogs.com/sjrb
-------------------------------------
签名:自己选的路,跪着也要走完;理想的实现,需要不懈奋斗!
-------------------------------------