luogu_4017题解最大食物链计数(拓扑排序)
Posted chriskkk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luogu_4017题解最大食物链计数(拓扑排序)相关的知识,希望对你有一定的参考价值。
题目:https://www.luogu.org/problemnew/show/P4017
由于这个题有严格的偏序关系(应该严格吧)。明显就可以想到拓扑排序。
用吃与被吃建图。同时记录出度与入度。
求拓扑排序的同时。如果谁的出度为 0 。则证明这条链到头。ans++。
最后输出答案。
代码如下:
这是邻接表存图的,速度比较快。
#include<bits/stdc++.h> #define sc(x) scanf("%d",&x) using namespace std; const int mod=80112002; struct edge int from,to,nxt; t[5000005]; int n,m,du[5005],chu[5005],f[5005],ans,head[5005]; queue<int> q; inline void topo() for(int i=1;i<=n;i++) if(du[i]==0) q.push(i),f[i]=1; while(!q.empty()) int now=q.front(); q.pop(); for(int i=head[now];i;i=t[i].nxt) int tt=t[i].to; f[tt]+=f[now]; f[tt]%=mod; du[tt]--; if(du[tt]==0) if(chu[tt]==0) ans+=f[tt]; ans%=mod; q.push(tt); int main() sc(n),sc(m); int tot=0; while(m--) int a,b; sc(a),sc(b); t[++tot].from=a;t[tot].to=b;t[tot].nxt=head[a]; head[a]=tot; du[b]++;chu[a]++; topo(); cout<<ans<<endl; // system("pause"); return 0;
然而最一开始我写的是vector的,感觉写的比较短,不用管那么多。
代码如下:
#include<bits/stdc++.h> #define sc(x) scanf("%d",&x) using namespace std; const int mod=80112002; struct edge int from,to; edge() edge(int _from,int _to): from(_from),to(_to) ; vector<edge> g[5000005]; int n,m,du[5005],chu[5005],f[5005],ans; queue<int> q; inline void topo() for(int i=1;i<=n;i++) if(du[i]==0) q.push(i),f[i]=1; while(!q.empty()) int now=q.front(); q.pop(); for(vector<edge>::iterator it=g[now].begin();it!=g[now].end();it++) int t=it->to; f[t]+=f[now]; f[t]%=mod; du[t]--; if(du[t]==0) if(chu[t]==0) ans+=f[t]; ans%=mod; q.push(t); int main() sc(n),sc(m); while(m--) int a,b; sc(a),sc(b); g[a].push_back(edge(a,b)); du[b]++;chu[a]++; topo(); cout<<ans<<endl; // system("pause"); return 0;
这个时空比较爆炸。
但是感觉还是挺好写的(滑稽)。
以上是关于luogu_4017题解最大食物链计数(拓扑排序)的主要内容,如果未能解决你的问题,请参考以下文章