题意:

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. CodeForce-810B Summer sell-off (结构体排序)

    http://codeforces.com/problemset/problem/810/B 已知n天里,已知第i天的供货量和需求量,给定一个f,可以在n天之中选f天促销使得供货量翻倍. 问选择其中f ...

  2. js特效代码-onmouseover/onclick 改变标签(背景)颜色

    <html> <head> <meta http-equiv="Content-Type" content="text/html; char ...

  3. PHP - 设计模式 - 观察者模式

    <?php//观察者模式//抽象通知者abstract class Subject { protected $observer = array() ; //添加观察者 public abstra ...

  4. 启动springboot出现错误 Caused by: java.net.BindException: Address already in use: bind

    如果运行过程中出现端口被占用 抛出了这个异常 首先可以在cmd中调出命令窗口然后 执行命令 netstat -ano  可以查看所有活动的连接  找到你被占用的端口 可以看到我被占用的端口的进程是 4 ...

  5. python并发与futures模块

    非并发程序(用于对比) 从网上下载20个国家的国旗图像: import os import time import sys import requests # 导入requests库 POP20_CC ...

  6. python学习1-博客-DB操作类

    #学习python,准备写一个博客,第一天:在别人代码基础上写一个数据库操作的db.py1)python代码 #!/usr/bin/env python # -*- coding: UTF-8 -*- ...

  7. P7737-[NOI2021]庆典【tarjan,虚树】

    正题 题目链接:https://www.luogu.com.cn/problem/P7737 题目大意 给出一张无向图满足若\(x\Rightarrow z,y\Rightarrow z\)那么有\( ...

  8. 一篇文章告诉你Python接口自动化测试中读取Text,Excel,Yaml文件的方法

    前言 不管是做Ui自动化和接口自动,代码和数据要分离,会用到Text,Excel,Yaml.今天讲讲如何读取文件数据 Python也可以读取ini文件,传送门 记住一点:测试的数据是不能写死在代码里面 ...

  9. Cookie实现是否第一次登陆/显示上次登陆时间

    Cookie实现是否第一次登陆/显示上次登陆时间 最近刚好看到Cookie这方面知识,对Servlet部分知识已经生疏,重新翻出已经遗弃角落的<JavaWeb开发实战经典>,重新温习了Co ...

  10. Pandas 数据的一些基本操作

    一个很偶然的机会,主动出击挑战一个之前没有尝试过的新东西,在做的过程中需要处理一些csv文件的数据,以下是我总结的一些小方法,希望对和我一样的新手朋友们有所帮助,初次尝试,望路过的朋友有更好的方法可以 ...