#include using namespace std; const int MAXN = 301; const long long INF = 1e12 + 8; long long adj[MAXN][MAXN], par[MAXN][MAXN], dist[MAXN][MAXN], N, Timer; vectorT[MAXN], in(MAXN), out(MAXN); void DFS(int node, int parent) { in[node] = Timer++; for(auto child : T[node]) if(child != parent) { DFS(child, node); } out[node] = Timer++; } int Process(int r) { Timer = 0; vector>TreeEdge(N+1, vector(N+1)); for(int i=1; i<=N; ++i) if(i!=r) { if(dist[r][i]==INF) continue; int p = par[r][i]; TreeEdge[i][p] = true; TreeEdge[p][i] = true; // Re-build Tree in Adjacency List T[p].push_back(i); } DFS(r, r); long long ret = INF; vectortoken(N+1); for(int i=1; i<=N; ++i) { token[i] = i; for(int anc=1; anc<=N; ++anc) if(anc!=r && in[anc]out[token[i]]) { token[i] = anc; } } for(int i=1; i<=N; ++i) { for(int j=1; j<=N; ++j) if(j!=r && j!=i) { if(TreeEdge[i][j]==false && adj[i][j]!=-1) { if(token[i]!=token[j]) { ret = min(ret, dist[r][i] + dist[r][j] + adj[i][j]); } } } } if(ret==INF) ret = -1; // Clean up for(int i=1; i<=N; ++i) { T[i].clear(); in[i] = out[i] = 0; } return ret; } void PlayGround() { cin >> N; for(int i=1; i<=N; ++i) { for(int j=1; j<=N; ++j) { cin >> adj[i][j]; if(adj[i][j]==-1) dist[i][j] = INF; else dist[i][j] = adj[i][j], par[i][j] = i; } } for(int k=1; k<=N; ++k) { for(int i=1; i<=N; ++i) { for(int j=1; j<=N; ++j) { long long x = dist[i][k] + dist[k][j]; if(dist[i][j] > x) { dist[i][j] = x; par[i][j] = par[k][j]; } } } } for(int r=1; r<=N; ++r) { cout << Process(r) << '\n'; } // cerr << "Time elapsed: " << 1.0 * clock() / CLOCKS_PER_SEC << " s.\n"; } int main() { PlayGround(); return 0; }