E - Reachability in Functional Graph

lightsong發表於2024-06-11

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
*/

相關文章