1. 程式人生 > >[題解]洛谷P4017 最大食物鏈計數

[題解]洛谷P4017 最大食物鏈計數

string algo queue 最大 edge toposort print con ()

一開始不知道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; }

[題解]洛谷P4017 最大食物鏈計數