给出两个点的距离,问你可以不可以由这些点组成一棵树,我们首先构造一个最小生成树,然后比较各各点之间的距离是否与题目给出的距离相等,可以用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;
}