题意:

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. TP5数据库数据变动日志记录设计

    根据网友的设计进行了部分调整: 用户分为管理员admin表和用户user表 记录操作表数据 增删改: insert/delete/update <?php /** * OperateLog.ph ...

  2. express 路由匹配和数据获取

    express配置路由只需要通过app.method(url,func)来配置,其中url配置和其中的参数获取方法不同 直接写全路径 路由中允许存在. get请求传入的参数 router.get(&q ...

  3. Shell系列(24)- 条件判断之文件类型

    按照文件类型进行判断 标红,记住:其他了解即可 测试选项 作用 -b 文件 判断该文件是否存在,并且是否为块设备文件(是块设备文件为真) -c 文件 判断该文件是否存在,并且是否为字符设备文件(是字符 ...

  4. Flutter 对状态管理的认知与思考

    前言 由 编程技术交流圣地[-Flutter群-] 发起的 状态管理研究小组,将就 状态管理 相关话题进行为期 两个月 的讨论. 目前只有内定的 5 个人参与讨论,如果你对 状态管理 有什么独特的见解 ...

  5. iPhone发布内测程序的方法

    iPhone是封闭系统,不像android手机可以自行安装apk,所以iPhone手机发布内测程序相对来说复杂一些. 越狱安装 如果测试用户的机器已经越狱,那就简单了,直接打包成ipa,用户直接通过9 ...

  6. 华为云计算IE面试笔记-云磁盘和普通磁盘的区别。

    1. 定义 云硬盘:一种虚拟块存储服务,主要为ECS和BMS提供块存储空间 普通磁盘:也称本地硬盘,指挂载在计算实例物理机上的本地硬盘 2. 性能 吞吐量具体情况具体分析.(若云磁盘用的SSD本地磁盘 ...

  7. 华为云计算IE面试笔记-eBackup有哪几种备份组网方式,各备份组网方式主要的应用场景及备份流程?

    应用场景: LAN-Base一般用于备份数据量小,且对备份窗口没有特殊要求的场景,此类场景下备份服务器和备份代理一般是虚拟机部署. LAN-Free一般用于备份数据量较大,且对备份窗口要求比较严格的场 ...

  8. CF235D-Graph Game【LCA,数学期望】

    正题 题目链接:https://www.luogu.com.cn/problem/CF235D 题目大意 给出一棵基环树,每次随机选择一个点让权值加上这个点的连通块大小然后删掉这个点. 求删光所有点时 ...

  9. 实验2:Open vSwitch虚拟交换机实践

    作业链接:实验2:Open vSwitch虚拟交换机实践 一.实验目的 能够对Open vSwitch进行基本操作: 能够通过命令行终端使用OVS命令操作Open vSwitch交换机,管理流表: 能 ...

  10. CentOS 7.9+19c单实例静默安装

    一.环境准备 二.解压文件 三.文件配置 四.安装 五.相关调整 六.打补丁 一.环境准备0.依赖包安装 rpm -q --qf '%{NAME}-%{VERSION}-%{RELEASE} (%{A ...