题意:

N个点。N行N列d[i][j]。

d[i][j]:结点i到结点j的距离。

问这N个点是否可能是一棵树。是输出YES,否则输出NO。

思路:

假设这个完全图是由一棵树得来的,则我们对这个完全图求最小生成树,得到原树。(画个图就明白)

故我们对完全图求最小生成树,然后用DFS从这棵树上的每个点出发,判断距离是否和矩阵d相同。

注意:

用vector存与每个点相连树枝的另一端,否则超时。用了vector也耗了1400多秒,限时2s。

代码:

#include <cstdio>
#include <iostream>
#include <string.h>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <vector>
#include <cmath>
#include <map>
#include <stack>
using namespace std;
int const uu[4] = {1,-1,0,0};
int const vv[4] = {0,0,1,-1};
typedef long long ll;
int const maxn = 50005;
int const inf = 0x3f3f3f3f;
ll const INF = 0x7fffffffffffffffll;
double eps = 1e-10;
double pi = acos(-1.0);
#define rep(i,s,n) for(int i=(s);i<=(n);++i)
#define rep2(i,s,n) for(int i=(s);i>=(n);--i)
#define mem(v,n) memset(v,(n),sizeof(v))
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
struct node{
int x,y,len;
};
int n;
int d[2005][2005], a[2005][2005];
int fa[2005];
node edge[4000005];
vector<int> graph[2005]; bool cmp(node a,node b){
return a.len<b.len;
} int findFa(int x){
if(fa[x]!=x) fa[x]=findFa(fa[x]);
return fa[x];
} bool dfs(int start,int x,int fa,int weight){
if(d[start][x]!=weight){
return false;
}
int L=graph[x].size();
rep(i,0,L-1){
int v=graph[x][i];
if(v==fa) continue;
bool t=dfs(start,v,x,weight+a[x][v]);
if(!t) return false;
}
return true;
} int main(){
scanf("%d",&n);
rep(i,1,n) rep(j,1,n) scanf("%d",&d[i][j]); rep(i,1,n) if(d[i][i]!=0){
printf("NO\n");
return 0;
}
rep(i,1,n-1) rep(j,i+1,n){
if(d[i][j]==0 || (d[i][j]!=d[j][i])){
printf("NO\n");
return 0;
}
} int eNum=0;
mem(a,0); rep(i,1,n-1) rep(j,i+1,n){
edge[++eNum].x=i, edge[eNum].y=j;
edge[eNum].len=d[i][j];
}
sort(edge+1,edge+1+eNum,cmp);
rep(i,1,n) fa[i]=i;
rep(i,1,n) graph[i].clear(); rep(i,1,eNum){
int xx=edge[i].x, yy=edge[i].y;
int fx=findFa(xx), fy=findFa(yy);
if(fx!=fy){
fa[fx]=fy;
a[xx][yy]=a[yy][xx]=edge[i].len;
graph[xx].push_back(yy);
graph[yy].push_back(xx);
}
} int t=findFa(1);
rep(i,2,n) if(findFa(i)!=t){
printf("NO\n");
return 0;
} rep(i,1,n){
bool k=dfs(i,i,-1,0); //从顶点i出发
if(!k){
printf("NO\n");
return 0;
}
}
printf("YES\n");
}

最新文章

  1. Oracle学习总结_day06_视图&amp;序列&amp;索引
  2. 学Android开发,入门语言java知识点
  3. [Hibernate] - many to many
  4. VBScript - CUD registry key and value
  5. string 常用 方法
  6. python生成器之斐波切纳数列
  7. PHP+Redis 不注意这些细节简直就是跳入一个出不来的坑(windows下安装)
  8. python+selenium自动化软件测试(第12章):Python读写XML文档
  9. 【nginx】中server配置说明
  10. JS的事件流的概念(重点)
  11. Java知多少(100)图像处理基础
  12. MySQL+InnoDB semi-consitent read原理及实现分析(转)
  13. 1.面向过程编程 2.面向对象编程 3.类和对象 4.python 创建类和对象 如何使用对象 5.属性的查找顺序 6.初始化函数 7.绑定方法 与非绑定方法
  14. Kafka 0.8 如何创建topic
  15. SecureCRT中使用 rz 上传文件 遇到 rz: command not found 的解决办法
  16. django的contenttype表
  17. (转)ZooKeeper-3.3.4集群安装配置
  18. android头像上传(获取头像加剪切)
  19. Scrum立会报告+燃尽图(十月二十三日总第十四次)
  20. 一次Ubuntu下的排雷记录

热门文章

  1. 洛谷P1090——合并果子(贪心)
  2. PHP中的PDO操作学习(三)预处理类及绑定数据
  3. PHP出现iconv(): Detected an illegal character in input string
  4. ATR吊灯止损策略 (含有tbquant源码)
  5. httprunner版本没有更新问题
  6. git 要求密码的解决方法:【生成gitLab公钥】:以及如何配置GitLab中的SSH key
  7. thinkphp5自带workerman应用
  8. [转载]linux环境变量设置方法总结(PATH/LD_LIBRARY_PATH)
  9. 华为云计算IE面试笔记-Fusionsphere架构及组件介绍(服务器虚拟化解决方案)
  10. P3643-[APIO2016]划艇【dp】