Codeforces Round #270(利用prim算法)
2 seconds
256 megabytes
standard input
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).
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.
If there exists such a tree, output "YES", otherwise output "NO".
3
0 2 7
2 0 9
7 9 0
YES
3
1 2 7
2 0 9
7 9 0
NO
3
0 2 2
7 0 9
7 9 0
NO
3
0 1 1
1 0 1
1 1 0
NO
2
0 0
0 0
NO
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算法)的更多相关文章
- Codeforces Round #270 1003
Codeforces Round #270 1003 C. Design Tutorial: Make It Nondeterministic time limit per test 2 second ...
- Codeforces Round #270 1002
Codeforces Round #270 1002 B. Design Tutorial: Learn from Life time limit per test 1 second memory l ...
- Codeforces Round #270 1001
Codeforces Round #270 1001 A. Design Tutorial: Learn from Math time limit per test 1 second memory l ...
- Codeforces Round #270 A~D
Codeforces Round #270 A. Design Tutorial: Learn from Math time limit per test 1 second memory limit ...
- Codeforces Round #270 D C B A
谈论最激烈的莫过于D题了! 看过的两种做法不得不ORZ,特别第二种,简直神一样!!!!! 1th:构造最小生成树. 我们提取所有的边出来按边排序,因为每次我们知道边的权值>0, 之后每次把边加入 ...
- Codeforces Round #270
A 题意:给出一个数n,求满足a+b=n,且a+b均为合数的a,b 方法一:可以直接枚举i,n-i,判断a,n-i是否为合数 #include<iostream> #include< ...
- codeforces水题100道 第七题 Codeforces Round #270 A. Design Tutorial: Learn from Math (math)
题目链接:http://www.codeforces.com/problemset/problem/472/A题意:给你一个数n,将n表示为两个合数(即非素数)的和.C++代码: #include & ...
- 多种方法过Codeforces Round #270的A题(奇偶法、打表法和Miller_Rabin(这个方法才是重点))
题目链接:http://codeforces.com/contest/472/problem/A 题目: 题意:哥德巴赫猜想是:一个大于2的素数一定可以表示为两个素数的和.此题则是将其修改为:一个大于 ...
- Codeforces Round #270 D Design Tutorial: Inverse the Problem --MST + DFS
题意:给出一个距离矩阵,问是不是一颗正确的带权树. 解法:先按找距离矩阵建一颗最小生成树,因为给出的距离都是最短的点间距离,然后再对每个点跑dfs得出应该的dis[][],再对比dis和原来的mp是否 ...
随机推荐
- 【WinRT】【译】【加工】在 XAML 中制作圆形图片
原文:[WinRT][译][加工]在 XAML 中制作圆形图片 原文地址:http://timheuer.com/blog/archive/2015/05/06/making-circular-ima ...
- C#开源汇总
原文:C#开源汇总 商业协作和项目管理平台-TeamLab 网络视频会议软件-VMukti 驰骋工作流程引擎-ccflow [免费]正则表达式测试工具-Regex-Tester Windows-Pho ...
- poj3678(two-sat)
传送门:Katu Puzzl 题意:n个点,点的取值可以是0或者1.m条边,有权值,有运算方式(并,或,异或),要求和这条边相连的两个点经过边上的运算后的结果是边的权值.问你有没有可能把每个点赋值满足 ...
- android-包签名
android-包签名 应用能在Android 系统上安装必须是经过有私有key的证书数据签名.Android系统通过证书确定应用的作者,和与应用建立信任关系.证书不会用于控制应用的安装.证书不需要权 ...
- cookie是指web浏览器存储的少量数据,该数据会在每次请求一个相关的URL时自动传到服务器中(转)
基本概念:cookie是指web浏览器存储的少量数据,该数据会在每次请求一个相关的URL时自动传到服务器中. 以博客园为例,我们看看cookie有哪些属性: 1.Name:cookie的名称: 2.V ...
- [置顶] JQuery实战总结三 标签页效果图实现
在浏览网站时我们会看到当我们鼠标移到多个选项卡上时,不同的选项卡会出现自己对应的界面的要求,在同一个界面上表达了尽量多的信息.大大额提高了空间的利用率.界面的切换效果也是不错的哦,这次自己可以实现啦. ...
- 怎样在屏幕上显示多个alv
本文解说怎样在屏幕上显示多个alv. 实现这种需求关键是下面几点(举例:在屏幕上显示4个alv): 1.须要定义4个alv control 2.由于有4个alv control,于是就须要定义4个容器 ...
- Windows phone 8 学习笔记(3) 通信
原文:Windows phone 8 学习笔记(3) 通信 Windows phone 8 可利用的数据通信方式比较广泛,在硬件支持的前提下,我们可以利用WiFi.蓝牙.临近感应等多种方式.数据交互一 ...
- REST Service 基础 A further step.
1. REST Service虽然实现简单, 但也功能丰富, 可以用来实现各种基于Web的服务(service). 2. REST Service的一些特点: 1)平台无关 2) 语言无关 3)基于H ...
- 主流芯片解决方案Ambarella的高清网络摄像机、德州仪器和控制海思
(本文由四川艾普作为数码科技有限公司 苏斌.范清华 收集) 高清网络视频监控发展到今天.正的高清时代.诸多有实力的高清摄像机厂家的产品线也逐渐完好起来,高清网络视频监控的配套产品有更加丰富和成熟.与此 ...