[題解]洛谷P4017 最大食物鏈計數
阿新 • • 發佈:2019-02-17
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; constint 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 最大食物鏈計數