D. Design Tutorial: Inverse the Problem
time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There is an easy way to obtain a new task from an old one called "Inverse the problem": we give an output of the original task, and ask to generate an input, such that solution to the original problem will produce the output we provided. The hard task of Topcoder
Open 2014 Round 2C, InverseRMQ, is a good example.

Now let's create a task this way. We will use the task: you are given a tree, please calculate the distance between any pair of its nodes. Yes, it is very easy, but the inverse version is a bit harder: you are given an n × n distance
matrix. Determine if it is the distance matrix of a weighted tree (all weights must be positive integers).

Input

The first line contains an integer n (1 ≤ n ≤ 2000)
— the number of nodes in that graph.

Then next n lines each contains n integers di, j (0 ≤ di, j ≤ 109)
— the distance between node i and node j.

Output

If there exists such a tree, output "YES", otherwise output "NO".

Sample test(s)
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
Note

In the first example, the required tree exists. It has one edge between nodes 1 and 2 with weight 2, another edge between nodes 1 and 3 with weight 7.

In the second example, it is impossible because d1, 1 should
be 0, but it is 1.

In the third example, it is impossible because d1, 2 should
equal d2, 1.

给定一个矩阵,表示每两个节点之间的权值距离,问能否够相应生成一棵树,

使得这棵树中的随意两点之间的距离和矩阵中的相应两点的距离相等。

思路:我们将给定的矩阵看成是一个图,a 到 b会有多条路径, 假设存在一棵树。那么

这个树中a->b的距离一定是这个图中全部a->b中路径长度最短的一条!

所以我们依据边权,

建立一棵MST树!

再将MST树中的随意两点之间的距离求出来,看是否和矩阵中的相应的节点

对距离同样,我们首先构造一个最小生成树,然后比較各各点之间的距离是否与题目给出的距离相等,能够用dfs搜索整张图的每两个点之间的距离.以下给的做法非dfs做的,用一个数组f[][],记录x,y两点之间的距离,算距离的时候是通过眼下点的前驱找,也就是说须要一个数组记录前驱,这样就能够不用dfs了,直接能够算.看完代码就明确了.....


#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 2010;
const int INF = 0x3f3f3f3f;
int graph[maxn][maxn];
int prior[maxn];
int visit[maxn];
int dis[maxn];
int f[maxn][maxn];
int n;
bool check()
{
for(int i = 0; i < n; i++)
{
dis[i] = INF;
if(graph[i][i] != 0) return false;
for(int j = i+1 ; j < n; j++)
{
if(graph[i][j] != graph[j][i] || graph[i][j] == 0) return false;
}
} memset(visit,0,sizeof(visit));
memset(prior,-1,sizeof(prior));
memset(f,0,sizeof(f));
int cent = n;
dis[0]=0;
while(cent--)//循环n次是由于要初始化
{ int min = -1;
for(int i = 0; i < n; i++)
{
if(!visit[i] && (min == -1 || dis[i] < dis[min]))
{
min = i;
}
}
for(int i = 0; i < n; i++)//在prim算法里面添加这层循环里面的内容算距离
{
if(visit[i])//必须是已经訪问过的点,才干算距离
{
f[i][min] = f[min][i] = f[i][prior[min]] + dis[min];
}
}
visit[min] = true;
for(int i = 0; i < n; i++)
{
if(dis[i] > graph[min][i] )
{
dis[i] = graph[min][i];
prior[i] = min;//记录前驱
}
}
} for(int i = 0; i < n; i++)
{
for(int j = 0 ; j < n; j++)
{
if(f[i][j] != graph[i][j])
{
return false;
}
}
}
return true;
}
int main()
{
#ifdef xxz
freopen("in","r",stdin);
#endif // xxz
while(cin>>n)
{
for(int i = 0; i < n; i++)
for(int j = 0; j < n; j++)
{
cin>>graph[i][j];
} if(check()) cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

Codeforces Round #270(利用prim算法)的更多相关文章

  1. Codeforces Round #270 1003

    Codeforces Round #270 1003 C. Design Tutorial: Make It Nondeterministic time limit per test 2 second ...

  2. Codeforces Round #270 1002

    Codeforces Round #270 1002 B. Design Tutorial: Learn from Life time limit per test 1 second memory l ...

  3. Codeforces Round #270 1001

    Codeforces Round #270 1001 A. Design Tutorial: Learn from Math time limit per test 1 second memory l ...

  4. Codeforces Round #270 A~D

    Codeforces Round #270 A. Design Tutorial: Learn from Math time limit per test 1 second memory limit ...

  5. Codeforces Round #270 D C B A

    谈论最激烈的莫过于D题了! 看过的两种做法不得不ORZ,特别第二种,简直神一样!!!!! 1th:构造最小生成树. 我们提取所有的边出来按边排序,因为每次我们知道边的权值>0, 之后每次把边加入 ...

  6. Codeforces Round #270

    A 题意:给出一个数n,求满足a+b=n,且a+b均为合数的a,b 方法一:可以直接枚举i,n-i,判断a,n-i是否为合数 #include<iostream> #include< ...

  7. codeforces水题100道 第七题 Codeforces Round #270 A. Design Tutorial: Learn from Math (math)

    题目链接:http://www.codeforces.com/problemset/problem/472/A题意:给你一个数n,将n表示为两个合数(即非素数)的和.C++代码: #include & ...

  8. 多种方法过Codeforces Round #270的A题(奇偶法、打表法和Miller_Rabin(这个方法才是重点))

    题目链接:http://codeforces.com/contest/472/problem/A 题目: 题意:哥德巴赫猜想是:一个大于2的素数一定可以表示为两个素数的和.此题则是将其修改为:一个大于 ...

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

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

随机推荐

  1. 修改emlog后台登录路径的方法(转)

    emlog后台登录地址的目录名称默认为admin,并且官方没有提供自定义后台登录入口名字的功能,这多少让我们觉得有些不安全,毕竟暴露一个网站的后台不是一件安全的事,今天就给您说下修改方法,增加一下网站 ...

  2. Java设置的读书笔记和集合框架Collection API

    一个.CollectionAPI 集合是一系列对象的聚集(Collection). 集合在程序设计中是一种重要的数据接口.Java中提供了有关集合的类库称为CollectionAPI. 集合实际上是用 ...

  3. Android中倒计时代码

    布局: maina.xml <DigitalClock android:id="@+id/myClock" android:layout_width="wrap_c ...

  4. Linux下搭建tomcat集群全记录(转)

    本文将讲述如何在Linux下搭建tomcat集群,以及搭建过程中可能的遇到的问题和解决方法.为简单起见,本文演示搭建的集群只有两个tomact节点外加一个apache组成,三者将安装在同一机器上:ap ...

  5. 使用python向Redis批量导入数据

    1.使用pipeline进行批量导入数据.包含先使用rpush插入数据,然后使用expire改动过期时间 class Redis_Handler(Handler): def connect(self) ...

  6. OpenStack 中的neutron-server启动过程

    neutron-server是neutron的核心组件之中的一个.负责直接接收外部请求,然后调用后端对应plugin进行处理. 其核心启动过程代码主要在neutron.server包中. __init ...

  7. SE 2014年5月23日

    两站点 A 和 B,由于业务往来需要,所以工程师提出vpn技术,同时需要保证业务流在internet上的安全性,同时在这里站点均为固定ip地址. 通过分析以上信息,确定这里使用 IPSec VPN的主 ...

  8. poj1155(树形dp)

    题目链接:http://poj.org/problem?id=1155 题意:电视台要直播一场比赛,电视网络刚好形成了一棵树,其中有M个为客户端,其他的为中转站,其中中转站与中转站以及中转站与客户端之 ...

  9. poj 3265 Problem Solving dp

    这个题目容易让人误以为是贪心就可以解决了,但是细想一下很容易举出反例. dp[i][j]表示解决了i个问题,最后一个月解决的问题数目. #include <iostream> #inclu ...

  10. 中国科学院信息project研究所 第四研究室实习生/应届生招聘

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvU2hpWmhpeGlu/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA ...