0w1

ABC 22 C - Blue Bird ( Floyd Warshall )

C: Blue Bird - AtCoder Beginner Contest 022 | AtCoder
Problem Statement: Given a graph of n ≤ 300 nodes and some edges, find the minimum weight sum of a cycle that starts from 1, goes to some other nodes and end in 1.
Basically, we will be finding a cycle that contains node 1. Definitely, there will be exactly 2 nodes connected with 1, one for out and one for in. We can simply enumerate these 2 nodes with O( n ^ 2 ), and update the minimum. We will use Floyd-Warshall algorithm to pre-calculate distance for each pair of nodes in O( n ^ 3 ). Note that this pre-calculated distance should not pass node 1 at all.

#include <bits/stdc++.h>
using namespace std;
const int MAXN = 300 + 2;
const int MAXM = MAXN * MAXN / 2;
const int MAXW = 1e5 + 5;
const int INF = 0x3f3f3f3f;

void upmin(int &x, int v){ if( x > v ) x = v; }

struct Edge{
    int u, v, w;
    Edge(int _u = 0, int _v = 0, int _w = 0): u(_u), v(_v), w(_w){}
} es[ MAXM * 2 ];

int n, m;
vector<int> G[ MAXN ];

int dis[ MAXN ][ MAXN ];

void solve(){
    memset( dis, INF, sizeof(dis) );
    for(int i = 1; i <= n; ++i) dis[ i ][ i ] = 0;
    for(int i = 1; i <= m; ++i)
        dis[ es[ i ].u ][ es[ i ].v ] = 
        dis[ es[ i ].v ][ es[ i ].u ] = es[ i ].w;
    for(int k = 2; k <= n; ++k)
        for(int i = 2; i <= n; ++i)
            for(int j = 2; j <= n; ++j)
                upmin( dis[ i ][ j ], dis[ i ][ k ] + dis[ k ][ j ] );
    int ans = INF;
    for(int i = 0; i < G[ 1 ].size(); ++i){
        int u = es[ G[ 1 ][ i ] ].v;
        for(int j = 0; j < G[ 1 ].size(); ++j){
            int v = es[ G[ 1 ][ j ] ].v;
            if( u == v ) continue;
            upmin( ans, es[ G[ 1 ][ i ] ].w + dis[ u ][ v ] + es[ G[ 1 ][ j ] ].w );
        }
    }
    if( ans == INF ) ans = -1;
    printf("%d\n", ans);
}

int main(){
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; ++i){
        int u, v, w; scanf("%d%d%d", &u, &v, &w);
        es[ i ] = Edge( u, v, w );
        G[ u ].push_back( i );
        es[ i * 2 ] = Edge( v, u, w );
        G[ v ].push_back( i * 2 );
    }
    solve();
    return 0;
}