Design Tutorial: Inverse the Problem

CodeForces - 472D

给你了一个 n × n最短距离矩阵。(即矩阵中dis[u][v]为u点到v点的最短距离),判断是否存在一个边权皆为正整数的树,恰好满足这个最短距离矩阵 。

Input

第一行为一个整数 n (1 ≤ n ≤ 2000) — 表示图中有多少个点.

下面 n 行,每行包括 n 个整数 di, j (0 ≤ di, j ≤ 109) — 点i和点j之间的最短距离.

Output

如果存在这样的树,输出 "YES", 否则输出"NO".

Examples

Input
3
0 2 7
2 0 9
7 9 0
Output
YES
Input
3
1 2 7
2 0 9
7 9 0
Output
NO
Input
3
0 2 2
7 0 9
7 9 0
Output
NO
Input
3
0 1 1
1 0 1
1 1 0
Output
NO
Input
2
0 0
0 0
Output
NO

sol:首先很明显的性质就是在树上,两个点之间一定有且仅有一条最短的路径,于是很明显用Kruskal把MST构建出来之后暴力dfs判断距离是否相等即可
Ps:根据样例可以特判掉很多奇奇怪怪的情况,比方说Dis[x][x]!=0或者Dis[x][y]!=Dis[y][x]等等(不过对答案毫无影响)
#include <bits/stdc++.h>
using namespace std;
typedef int ll;
inline ll read()
{
ll s=;
bool f=;
char ch=' ';
while(!isdigit(ch))
{
f|=(ch=='-'); ch=getchar();
}
while(isdigit(ch))
{
s=(s<<)+(s<<)+(ch^); ch=getchar();
}
return (f)?(-s):(s);
}
#define R(x) x=read()
inline void write(ll x)
{
if(x<)
{
putchar('-'); x=-x;
}
if(x<)
{
putchar(x+''); return;
}
write(x/);
putchar((x%)+'');
return;
}
#define W(x) write(x),putchar(' ')
#define Wl(x) write(x),putchar('\n')
const int N=,M=;
int n,Dis[N][N];
namespace Tree
{
int tot=,Next[M],to[M],val[M],head[N];
int cnt=;
struct Edge
{
int U,V,Quan;
inline bool operator<(const Edge &tmp)const
{
return Quan<tmp.Quan;
}
}E[M];
inline void add(int x,int y,int z)
{
Next[++tot]=head[x];
to[tot]=y;
val[tot]=z;
head[x]=tot;
}
int Father[N];
inline int GetFa(int x)
{
return (Father[x]==x)?(Father[x]):(Father[x]=GetFa(Father[x]));
}
int Root,Path[N][N];
inline void dfs(int x,int fa,int Sum)
{
int i; Path[Root][x]=Sum;
for(i=head[x];i;i=Next[i]) if(to[i]!=fa)
{
dfs(to[i],x,Sum+val[i]);
}
}
inline void Solve()
{
int i,j;
for(i=;i<=n;i++)
{
Father[i]=i;
for(j=;j<i;j++) E[++cnt]=(Edge){j,i,Dis[j][i]};
}
sort(E+,E+cnt+);
for(i=;i<=cnt;i++)
{
Edge tmp=E[i];
int x=tmp.U,y=tmp.V,z=tmp.Quan;
int xx=GetFa(x),yy=GetFa(y);
if(xx==yy) continue;
Father[xx]=yy;
add(x,y,z);
add(y,x,z);
}
for(i=;i<=n;i++) Root=i,dfs(i,,);
for(i=;i<=n;i++)
{
for(j=;j<=n;j++) if(Path[i][j]!=Dis[i][j])
{
puts("NO"); exit();
}
}
puts("YES");
}
}
int main()
{
int i,j;
R(n);
for(i=;i<=n;i++)
{
for(j=;j<=n;j++) R(Dis[i][j]);
}
for(i=;i<=n;i++)
{
if(Dis[i][i]) return puts("NO"),;
for(j=;j<i;j++) if((Dis[j][i]!=Dis[i][j])||(!Dis[j][i])) return puts("NO"),;
}
Tree::Solve();
return ;
}
/*
Input
3
0 2 7
2 0 9
7 9 0
Output
YES Input
3
1 2 7
2 0 9
7 9 0
Output
NO Input
3
0 2 2
7 0 9
7 9 0
Output
NO Input
3
0 1 1
1 0 1
1 1 0
Output
NO Input
2
0 0
0 0
Output
NO
*/
 

codeforces472D的更多相关文章

随机推荐

  1. Excel Metadata

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  2. 利用Swig转换C++代码为C#可用的代码

    详细的文件路径为:http://user.qzone.qq.com/1259374136/blog/1432887689 Swig学习教程 1.Swig的基本介绍 SWIG(Simplified Wr ...

  3. MAVLink Linux/QNX/MacOs Integration Tutorial (UDP)

    MAVLink Linux/QNX/MacOs Integration Tutorial (UDP) Overview This program was written to test the udp ...

  4. Python Basics

    廖雪峰老师博客 1. 可变参数(例如 *nums),允许传入一个list 或 tuple,但是 关键字参数(例如 **kv),允许传入一个dict,具体可参考此页: 2. set与dict类似,但只是 ...

  5. 自定义动画(仿Win10加载动画)

    一.源代码 源代码及demo 二.背景 先看看Win10的加载动画(找了很久才找到): CPA推广甲爪广告联盟满30日结 [点击进入] 甲爪广告联盟,提供各类高单价CPA广告 单价高 收益好 日付广告 ...

  6. 131.003 数据预处理之Dummy Variable & One-Hot Encoding

    @(131 - Machine Learning | 机器学习) Demo 直观来说就是有多少个状态就有多少比特,而且只有一个比特为1,其他全为0的一种码制 {sex:{male, female}}​ ...

  7. PHP后台处理jQuery Ajax跨域请求问题 — xx was not called解决办法

    // 前台代码 $.ajax({ url: 'http://www.ushark.net/home/save_trial_apply', dataType: 'jsonp', processData: ...

  8. RoCE、softRoCE与iWRAP

    RoCE - RDMA over Converged Ethernet 以太网在全球互联的广域网中毫无异议的老大,但在高带宽.低延时的专有网络领域却明显混不开.伴随网络融合概念兴起,IETF发布了DC ...

  9. Python用户交互-密码不可见

    输入密码时若让用户不可见,可以使用getpass模块中的getpass方法 # 输入密码时若想要不可见,使用getpass模块中getpass方法即可 import getpass pwd=getpa ...

  10. 从golang-gin-realworld-example-app项目学写httpapi (一)

    https://wangzitian0.github.io/2013/06/29/zero-to-one-1/ https://github.com/gothinkster/golang-gin-re ...