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的更多相关文章
随机推荐
- 【SSH网上商城项目实战01】整合Struts2、Hibernate4.3和Spring4.2
转自:https://blog.csdn.net/eson_15/article/details/51277324 今天开始做一个网上商城的项目,首先从搭建环境开始,一步步整合S2SH.这篇博文主要总 ...
- C#学习笔记-接口与抽象类
namespace ClassLesson { class Program { static void Main(string[] args) { ); Console.WriteLine(perso ...
- Aizu2292 Common Palindromes
题意 我也不知道哪里来的OJ \(vjudge\) 上的 给定两个字符串 \(S,T\) ,询问 \((i,j,k,l)\) 这样的四元组个数 使得 \(S[i,j],T[k,l]\) 是相等的回文串 ...
- 最简单,有效的学习mysql教程(一)
数据库 1 定义 数据库,可以简单的解释为:高效的存储和处理数据的介质(主要分为磁盘和内存两种). 2 分类 根据数据库存储介质的不同,可以将其分为两类,即:关系型数据库(SQL)和非关系型数据库(N ...
- <Android 基础(二十一)> Android 屏幕适配
基本概念 1. 什么是屏幕尺寸.屏幕分辨率.屏幕像素密度? 屏幕尺寸是指屏幕对角线的长度.单位是英寸,1英寸=2.54厘米 屏幕分辨率是指在横纵向上的像素点数,单位是px,1px=1像素点,一般是纵向 ...
- sudo的安装
关于mini版的centos7的是不能直接sudo命令的 下面我来说一下怎么让sudo命令生效 第一步 先切换到root用户: su - 第二步 visudo 给相应用户分配sudo的权限 第三 ...
- 为订阅内虚拟机批量安装并配置 Microsoft Anti-Malware 扩展
本文提供了对订阅内的 Windows 经典部署虚拟机和资源管理器部署虚拟机执行批量安装并配置 Microsoft Anti-Malware 扩展的 PowerShell 脚本. 关于安装 Window ...
- Java中执行.exe文件
public static void main(String args[]){ try { String command ="notepad"; // 笔记本 Process ch ...
- 打通版微社区(5):部署DZ3.2
参考官方帖子http://www.discuz.net/thread-3258186-1-1.html 这是第三方的帖子http://www.discuz.net/thread-3199850-1- ...
- Asp.Net MVC Identity 2.2.1 使用技巧(二)
之前我们看到了新生成的项目中跟identity有关的有四个文件,这些文件是基础功能,并未开启identity的全部功能.现在我们先启用角色功能. 1.在App_Start文件夹中的IdentityCo ...