E - Reachability in Functional Graph
https://atcoder.jp/contests/abc357/tasks/abc357_e
思路
概念:
基環樹-內生樹。
https://www.cnblogs.com/Dfkuaid-210/p/14696378.html
方法:
使用拓撲排序,從入度為0的點開始,依此從外層向內層拆點,直到剩下環, 拆換過程中把拆掉的size記到目標點上size,依次累計到環點上。
最後統計環點上的所有點的size之和。
Code
https://atcoder.jp/contests/abc357/submissions/54442574
#include <bits/stdc++.h> using namespace std; #define int long long int to[200005],deg[200005],sz[200005]; vector<int>v; int sum=0; void dfs(int u){ deg[u]=0; v.push_back(u); sum+=sz[u]; if(deg[to[u]])dfs(to[u]); } signed main(){ int n; cin>>n; queue<int>q; for(int i=1;i<=n;i++)cin>>to[i],sz[i]=1,deg[to[i]]++; for(int i=1;i<=n;i++)if(deg[i]==0)q.push(i); while(!q.empty()){ int u=q.front(); q.pop(); deg[to[u]]--; sz[to[u]]+=sz[u]; if(deg[to[u]]==0){ q.push(to[u]); } } for(int i=1;i<=n;i++){ if(deg[i]){ sum=0; v.clear(); dfs(i); for(int a:v)sz[a]=sum; } } int ans=0; for(int i=1;i<=n;i++){ ans+=sz[i]; } cout<<ans; } /* things to check 0.delete cerr code or use '//' 1.initallize(especially multicases) 2.int overflow/long long mle 3.if make the ans is hard , try 2-divided 4.memory &b-&a 5.function canshu position 6.the format of input 7.size enough ? 8.the name of function 9.stop copying x0->y0 */