0w1

GCJ 2016 R1A pC. BFFs ( Graph Adhoc )

Dashboard - Round 1A 2016 - Google Code Jam
There are two possible ways to form a maximum cycle:
1. Sum up for each pair ( u, v ) that share bidirectional edges, length of chain that starts with u, and v, such like f[ f[ .. f[ v ] ] ] <- f[ .. f[ v ] ] .. <- v <-> u -> f[ u ] .., where a directional arrow from x -> y shows that having x, y will be considered valid to exist next to x.
2. Maximum length of a directed cycle.

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e3 + 3;

int n;
int f[ MAXN ];

int maxLenDirectedCycle(){
    int res = 0;
    vector< int > depth( n + 1 );
    for( int u = 1; u <= n; ++u ){
        fill( depth.begin(), depth.end(), -1 );
        int cur = u;
        int cnt = 0;
        while( true ){
            depth[ cur ] = cnt++;
            if( depth[ f[ cur ] ] != -1 ){
                cnt = depth[ cur ] - depth[ f[ cur ] ] + 1;
                break;
            }
            cur = f[ cur ];
        }
        res = max( res, cnt );
    }
    return res;
}

vector< int > G[ MAXN ]; // G[ u ] stores people that need u
int vis[ MAXN ];

int getMaxLen( int u, int fa ){
    vis[ u ] = 1;
    int res = 1;
    for( int v : G[ u ] ){
        if( v == fa ) continue;
        if( vis[ v ] ) continue;
        res = max( res, getMaxLen( v, u ) + 1 );
    }
    return res;
}

int maxLenTwoChain(){
    int res = 0;
    memset( vis, 0, sizeof( vis ) );
    for( int i = 1; i <= n; ++i )
        G[ i ].clear();
    for( int u = 1; u <= n; ++u )
        G[ f[ u ] ].push_back( u );
    for( int u = 1; u <= n; ++u ) if( u == f[ f[ u ] ] ){
        if( vis[ u ] ) continue;
        res += getMaxLen( u, f[ u ] ) + getMaxLen( f[ u ], u );
    }
    return res;
}

void solve(){
    int ans1 = maxLenDirectedCycle();
    int ans2 = maxLenTwoChain();
    printf( "%d\n", max( ans1, ans2 ) );
}

int main(){
    int T; scanf( "%d", &T );
    for( int kase = 1; kase <= T; ++kase ){
        printf( "Case #%d: ", kase );
        scanf( "%d", &n );
        for( int i = 1; i <= n; ++i )
            scanf( "%d", f + i );
        solve();
    }
    return 0;
}