题意:

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");
}

cf Inverse the Problem (最小生成树+DFS)的更多相关文章

  1. Codeforces Round #270 D Design Tutorial: Inverse the Problem --MST + DFS

    题意:给出一个距离矩阵,问是不是一颗正确的带权树. 解法:先按找距离矩阵建一颗最小生成树,因为给出的距离都是最短的点间距离,然后再对每个点跑dfs得出应该的dis[][],再对比dis和原来的mp是否 ...

  2. Codeforces #270 D. Design Tutorial: Inverse the Problem

    http://codeforces.com/contest/472/problem/D D. Design Tutorial: Inverse the Problem time limit per t ...

  3. cf472D Design Tutorial: Inverse the Problem

    D. Design Tutorial: Inverse the Problem time limit per test 2 seconds memory limit per test 256 mega ...

  4. D. Design Tutorial: Inverse the Problem 解析含快速解法(MST、LCA、思維)

    Codeforce 472D Design Tutorial: Inverse the Problem 解析含快速解法(MST.LCA.思維) 今天我們來看看CF472D 題目連結 題目 給你一個\( ...

  5. CF 291E. Tree-String Problem [dfs kmp trie图优化]

    CF291E 题意:一棵树,每条边上有一些字符,求目标串出现了多少次 直接求目标串的fail然后一边dfs一边跑kmp 然后就被特殊数据卡到\(O(n^2)\)了... 因为这样kmp复杂度分析的基础 ...

  6. 【CF】270D Design Tutorial: Inverse the Problem

    题意异常的简单.就是给定一个邻接矩阵,让你判定是否为树.算法1:O(n^3).思路就是找到树边,原理是LCA.判断树边的数目是否为n-1.39-th个数据T了,自己测试2000跑到4s.算法2:O(n ...

  7. Design Tutorial: Inverse the Problem

    Codeforces Round #270 D:http://codeforces.com/contest/472/problem/D 题意:给以一张图,用邻接矩阵表示,现在问你这张图能不能够是一棵树 ...

  8. HDU 2489 Minimal Ratio Tree 最小生成树+DFS

    Minimal Ratio Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Other ...

  9. CodeForces160D 最小生成树 + dfs

    https://cn.vjudge.net/problem/26727/origin 题目大意: 给一个带权的无向图,保证没有自环和重边. 由于最小生成树不唯一,因此你需要确定每一条边是以下三种情况哪 ...

随机推荐

  1. 解决vscode可以编译通过c++项目,但头文件有红色波浪线的问题

    解决vscode可以编译通过c++项目,但头文件有红色波浪线的问题 一.问题描述 我是在Ubuntu 16.04的环境下,用vscode写代码的,一般不使用vscode自带的编译环境,而是用cmake ...

  2. PHP中的文件系统函数(一)

    从这篇文章开始,我们将学习一系列的 PHP 文件系统相关函数.其实这些函数中,有很多都是我们经常用到的,大家并不需要刻意地去记住它们,只要知道有这么个东西,在使用的时候记得来查文档就可以了. 文件路径 ...

  3. C++ 找零钱方法数

    * 动态规划法 #include "stdafx.h" #include <iostream> #include <vector> using std::v ...

  4. tomcat 跨域的配置

    * 允许所有跨域  E:\apache-tomcat-7.0.81\conf\web.xml  <filter> <filter-name>CorsFilter</fil ...

  5. fastjson将json转为Map<String,String>踩坑

    字符串 对于一个json字符串 String str = "{"specItem":"[红, 大]","specName":&qu ...

  6. farOs 介绍

    nGame nGame 一款文字游戏服务端框架;用于快速构建:自由探索.武侠.修真.模拟,回合制,剧本杀.动态语言小说.等服务器 如果你有期望实现的功能请加Q群 ngame计划 完善框架功能 farO ...

  7. CSP初赛考点汇总

    qwq 为SCP初赛选手(我)收集的各种定理qwq 更新: 1.为了初赛都能用,不限于定理了 2.主旨为在短时间内复习各算法,备初赛 3.请确定你学习(学懂了)了 \(\texttt{oi}\) 的基 ...

  8. 自然语言处理标注工具——Brat(安装、测试、使用)

    一.Brat标注工具安装 1.安装条件: (1)运行于Linux系统(window系统下虚拟机内linux系统安装也可以) (2)目前brat最新版本(v1.3p1)仅支持python2版本运行使用( ...

  9. react之组建通信

    父组件与子组件通信 父组件将自己的状态传递给子组件,子组件当做属性来接收,当父组件更改自己状态的时候,子组件接收到的属性就会发生改变 父组件利用ref对子组件做标记,通过调用子组件的方法以更改子组件的 ...

  10. Redis大集群扩容性能优化实践

    一.背景 在现网环境,一些使用Redis集群的业务随着业务量的上涨,往往需要进行节点扩容操作. 之前有了解到运维同学对一些节点数比较大的Redis集群进行扩容操作后,业务侧反映集群性能下降,具体表现在 ...