#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int maxn = 2005;
struct Edge {
int from, to, cost;
bool operator < (const Edge &temp) const {
return cost < temp.cost;
}
}edge[maxn*maxn];
int n, a[maxn][maxn], tot, head[maxn];
struct E { int to, cost, next; } e[maxn*maxn];
void init() { tot = 0; memset(head, -1, sizeof(head)); }
void addedge(int u, int v, int cost) {
e[++tot].to = v; e[tot].cost = cost; e[tot].next = head[u];
head[u] = tot;
}
int par[maxn], ran[maxn];
int query(int x) { return par[x] == x ? x : par[x] = query(par[x]); }
bool unite(int x, int y) {
x = query(x), y = query(y);
if (x == y) return false;
if (ran[x] < ran[y]) par[x] = y;
else {
par[y] = x;
if (ran[x] == ran[y]) ran[x]++;
}
return true;
}
ll dis[maxn];
void dfs(int u, int f, ll d) {
dis[u] = d;
for (int i = head[u]; ~i; i = e[i].next) {
int v = e[i].to, cost = e[i].cost;
if (v == f) continue;
dfs(v, u, d + cost);
}
}
int iabs(int x) { return x > 0 ? x : -x; }
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
scanf("%d", &a[i][j]);
}
}
bool ok = true;
int cnt = 0;
for (int i = 1; i <= n; i++) {
for (int j = i; j <= n; j++) {
if (i == j && a[i][j] != 0) { ok = false; i = n + 1; break; }
if (a[i][j] != a[j][i]) { ok = false; i = n + 1; break; }
if (a[i][j] == 0) continue;
edge[++cnt].from = i;
edge[cnt].to = j;
edge[cnt].cost = a[i][j];
}
}
if (!ok) { printf("NO\n"); return 0; }
sort(edge+1, edge+1+cnt);
init();
for (int i = 1; i <= n; i++) par[i] = i, ran[i] = 0;
int num = 0;
for (int i = 1; i <= cnt && num < n - 1; i++) {
int u = edge[i].from, v = edge[i].to, cost = edge[i].cost;
if (unite(u, v)) {
++num;
addedge(u, v, cost); addedge(v, u, cost);
}
}
if (num != n - 1) { printf("NO\n"); return 0; }
for (int i = 1; i <= n; i++) {
memset(dis, 0, sizeof(dis));
dfs(i, -1, 0);
for (int j = 1; j <= n; j++) {
if (i == j) continue;
if (dis[j] != a[i][j]) { ok = false; i = n + 1; break; }
}
}
if (ok) printf("YES\n");
else printf("NO\n");
return 0;
}
CodeForces - 472D Design Tutorial: Inverse the Problem——最小生成树
原创
©著作权归作者所有:来自51CTO博客作者软糖酱八号机的原创作品,请联系作者获取转载授权,否则将追究法律责任
提问和评论都可以,用心的回复会被更多人看到
评论
发布评论
相关文章
-
【codeforces】 472C Design Tutorial: Make It Nondeterministic
简单贪心。。。。
codeforces #include #define i++ -
Design Tutorial: Learn from Math CodeForces - 472A(数论基础)
题意:任何不小
#include ios #define -
最小生成树
三维空间中给定 n 个点,在任意两点之间连一条边的代价为它们的曼哈顿距离,求最小生成树。 ...
最小生成树 曼哈顿距离 编程题 -
java sharding分库查询
ShardingSphere的介绍 ShardingSphere是一款起源于当当网内部的应用框架。2015年在当当网内部诞 生,最初就叫ShardingJDBC。2016年的时候,由其中一个主要的开发人员张亮, 带入到京东数科,组件团队继续开发。在国内历经了当当网、电信翼支付、京东数 科等多家大型互联网企
java sharding分库查询 spring boot java 后端 sharding