codeforces472D
Design Tutorial: Inverse the Problem
给你了一个 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
3
0 2 7
2 0 9
7 9 0
YES
3
1 2 7
2 0 9
7 9 0
NO
3
0 2 2
7 0 9
7 9 0
NO
3
0 1 1
1 0 1
1 1 0
NO
2
0 0
0 0
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的更多相关文章
随机推荐
- MySQL B+树索引和哈希索引的区别(转 JD二面)
导读 在MySQL里常用的索引数据结构有B+树索引和哈希索引两种,我们来看下这两种索引数据结构的区别及其不同的应用建议. 二者区别 备注:先说下,在MySQL文档里,实际上是把B+树索引写成了BTRE ...
- Thymeleaf学习记录(5)--运算及表单
Thymeleaf文本及预算: 字面 文本文字:'one text','Another one!',... 号码文字:0,34,3.0,12.3,... 布尔文字:true,false 空字面: nu ...
- Redis实现分布式锁2
redisTemplate实现分布式锁 /** * 分布式锁-加锁 * @param key * @param value 当前时间+超时时间 System.currentTimeMillis()+t ...
- sql:SQL Server metadata queries
http://www.mssqltips.com/sqlservertip/3449/making-sql-server-metadata-queries-easier-with-these-new- ...
- python保存字典和读取字典pickle
import pickle import numpy as np def save_obj(obj, name): with open(name + '.pkl', 'wb') as f: pickl ...
- vue-router初涉
概念: vue-router: vue官方路由插件. 路由: 指单页面应用的路径管理系统.在vue中都是单页应用,相当于只有一个index.html页面,所以无法使用<a>标签,我们使用路 ...
- FCC的javascript初级算法题解答
FCC上的javascript基础算法题 前一阵子做的基础算法题,感觉做完后收获还蛮大的,现在将自己的做法总结出来,供大家参考讨论.基本上做到尽量简短有效,但有些算法还可以继续简化,比如第七题若采用正 ...
- MyBatis基本配置和实践(五)
第一步:创建一个Maven工程 第二步:编辑Maven工程的pom.xml,引入mybatis-generator-maven-plugin <?xml version="1.0&qu ...
- 关于serialVersionUID与序列化"
java序列化trick and trap 厂内经常出现序列化对象版本不匹配问题,于是发本文说明一些序列化的注意点 调用MQ.memcached.rpc等等涉及到远程通讯的都会经过序列化,虽然客户端透 ...
- [转]实现Hive数据同步更新的shell脚本
引言: 上一篇文章<Sqoop1.4.4 实现将 Oracle10g 中的增量数据导入 Hive0.13.1 ,并更新Hive中的主表>http://www.linuxidc.com/Li ...