Codeforces Round #270(利用prim算法)

简介:
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;
}




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










本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/4752178.html,如需转载请自行联系原作者


相关文章
|
算法
最小生成树算法:Prim算法
在图论中,最小生成树(Minimum Spanning Tree,简称MST)是一种常用的算法问题。最小生成树是指在一个加权连通图中选取边的子集,使得所有顶点都被覆盖,并且边的总权值最小。
268 0
|
1月前
|
算法 决策智能
基于prim算法求出网络最小生成树实现网络社团划分和规划
该程序使用MATLAB 2022a版实现路线规划,通过排序节点权值并运用Prim算法生成最小生成树完成网络规划。程序基于TSP问题,采用遗传算法与粒子群优化算法进行路径优化。遗传算法通过编码、选择、交叉及变异操作迭代寻优;粒子群优化算法则通过模拟鸟群觅食行为,更新粒子速度和位置以寻找最优解。
|
3月前
|
机器学习/深度学习 算法 Java
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
这篇文章介绍了基于贪婪技术思想的Prim算法和Dijkstra算法,包括它们的伪代码描述、Java源代码实现、时间效率分析,并展示了算法的测试用例结果,使读者对贪婪技术及其应用有了更深入的理解。
算法设计(动态规划应用实验报告)实现基于贪婪技术思想的Prim算法、Dijkstra算法
|
4月前
|
机器学习/深度学习 人工智能 算法
|
5月前
|
算法 C语言
数据结构与算法——最小生成树问题(什么是最小生成树、Prim算法、Kruskal算法)
数据结构与算法——最小生成树问题(什么是最小生成树、Prim算法、Kruskal算法)
34 0
|
算法 C++
用prim和kruskal算法求最小生成树问题
用prim和kruskal算法求最小生成树问题
84 0
|
供应链 算法 Java
java数据结构最经济的地下通道建设方案prim算法
MX是世界上第一大传媒娱乐企业,该公司数十年的经营历史中创作了很多经典影片,此外还经营着很多的规模十分宏大世界级的主题娱乐公园。最近MX公司刚和C国X城市达成协定,共同投资建设C国国内唯一一家主题娱乐公园。
60 0
|
算法 Java
数据结构(13)最小生成树JAVA版:prim算法、kruskal算法
13.1.概述 最小生成树,包含图的所有顶点的一棵树,树的边采用包含在图中的原有边中权重和最小的边。翻译成人话就是遍历一遍全图所有顶点的最短路径,这条路径就叫最小生成树。 最小生成树存在和图是连通图互为充要条件,顶点都不连通,肯定不可能有路能遍历一遍全图。 求解最小生成树有两种常用算法:
171 0
|
算法
Prim算法和Kruskal算法到底哪个好?
Prim算法和Kruskal算法到底哪个好?
204 0
|
算法
大话数据结构--Prim算法
大话数据结构--Prim算法
109 0