Let's think it in the following way: for the minimal length edge, it must belong the the tree, ..., for the k-th minimal length edge(a, b), if there is already an path between a-b, then it can not be an edge of tree anymore, otherwise it must be edge of tree, why? Because otherwise there must be a path from a to b in the tree, that means a and b can be connected by edges with less length, but a and b is not connected.
So this Kruskal style analysis gives us this theorem: if there is an answer, then the answer must be the MST of that graph. (You can also guess this theorem and try to prove it.)
You can solve MST in O(n^2 log n), and then there are many way to check distance between notes on tree: you can just simply do dfs or bfs from each node, it can run in O(n^2). Or if you have pre-coded LCA algorithm, it can run in O(n^2 log n).
#include <iostream>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <bitset>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <climits>
#include <cstdlib>
#include <cmath>
#include <time.h>
#define maxn 3005
#define maxm 40005
#define eps 1e-10
#define mod 10000007
#define INF 2e9
#define lowbit(x) (x&(-x))
#define mp make_pair
#define ls o<<1
#define rs o<<1 | 1
#define lson o<<1, L, mid
#define rson o<<1 | 1, mid+1, R
typedef long long LL;
typedef unsigned long long ULL;
//typedef int LL;
using namespace std;
LL qpow(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base;base=base*base;b/=2;}return res;}
LL powmod(LL a, LL b){LL res=1,base=a;while(b){if(b%2)res=res*base%mod;base=base*base%mod;b/=2;}return res;}
void scanf(int &__x){__x=0;char __ch=getchar();while(__ch==' '||__ch=='\n')__ch=getchar();while(__ch>='0'&&__ch<='9')__x=__x*10+__ch-'0',__ch = getchar();}
LL gcd(LL _a, LL _b){if(!_b) return _a;else return gcd(_b, _a%_b);}
//head
int g[maxn][maxn];
int n;
void read(void)
{
scanf("%d", &n);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
scanf("%d", &g[i][j]);
}
void work(void)
{
int pos, mi;
bool ok = 1;
for(int i = 1; i <= n; i++) if(g[i][i]) ok = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(g[i][j] != g[j][i]) ok = 0;
for(int i = 1; i <= n && ok; i++) {
mi = INF;
for(int j = 1; j <= n; j++) {
if(j == i) continue;
if(mi > g[i][j]) mi = g[i][j], pos = j;
}
if(mi <= 0) ok = 0;
for(int j = 1; j <= n; j++) {
if(j == i || j == pos) continue;
if(abs(g[i][j] - g[pos][j]) != mi) ok = 0;
}
}
if(ok) printf("YES\n");
else printf("NO\n");
}
int main(void)
{
read();
work();
return 0;
}