列表

详情


NC201988. 导航系统

描述

小 Q 所在的国家有 N 个城市,城市间由 N-1 条双向道路连接,任意一对城市都是互通的。
每条道路有一个长度,自然,小 Q 的导航系统能显示每对城市间的最短距离。
但是小 Q 对这个系统并不太放心,于是他向你求助:
给定每对城市间的最短距离,你要判断距离表是否一定有误。
如果这张距离表是自洽的,那么请你按升序依次给出每条道路的长度。
对于全部的数据,1≤N≤500,输入的所有数字都是不超过 109 的非负整数。

输入描述

第一行一个数字 N
接下来 N 行,每行 N 个正整数
第 i 行第 j 列的数字表示城市 i 和城市 j 间的最短距离
保证第 i 行第 i 列的数字为 0

输出描述

第一行,一个字符串
如果距离表没有问题,输出“Yes”
并在接下来的 N-1 行从小到大给出每条道路的长度
否则输出“No”即可

示例1

输入:

3
0 1 2
1 0 1
2 1 0

输出:

Yes
1
1

示例2

输入:

3
0 1 1
1 0 1
1 1 0

输出:

No

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 385ms, 内存消耗: 4452K, 提交时间: 2020-02-15 15:42:39

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
#define ll long long
int n,num[505],top,opt;
ll inf=1e9+1;
ll chk[505][505];
ll ans[505][505];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		scanf("%lld",&chk[i][j]);
		if(j<i&&chk[i][j]!=chk[j][i]){opt=1;}
		ans[i][j]=chk[i][j];
	}
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	ans[i][j]=min(ans[i][j],ans[i][k]+ans[k][j]);
	
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		if(ans[i][j]!=chk[i][j])opt=1;
	}
	
	
	for(int k=1;k<=n;k++)
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	if(i!=j&&j!=k&&i!=k&&ans[i][j]==ans[i][k]+ans[k][j])ans[i][j]=inf;
	for(int i=1;i<=n;i++)
	for(int j=i+1;j<=n;j++)
	{
		if(ans[i][j]!=inf)num[++top]=ans[i][j];
	}
	if(top!=n-1)opt=1;
	if(opt){printf("No");return 0;}
	printf("Yes\n");
	sort(num+1,num+n);
	for(int i=1;i<n;i++)
	{
		printf("%lld\n",num[i]);
	}
	
	return 0;
}

C++14(g++5.4) 解法, 执行用时: 76ms, 内存消耗: 2788K, 提交时间: 2020-02-16 14:00:25

#include<bits/stdc++.h>
using namespace std;
const int maxn=505;
long long e[maxn][maxn];
bool bk[maxn][maxn];
vector <long long> v;
int main()
{
	int n;scanf("%d",&n);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++)
			scanf("%lld",&e[i][j]);
	}
	for(int i=1;i<=n;i++){
		for(int j=i+1;j<=n;j++){
			bool flag=true;
			for(int k=1;k<=n;k++){
				if((e[i][j]+e[j][k]!=e[i][k]||bk[i][k])&&
					(e[j][i]+e[i][k]!=e[j][k]||bk[j][k])){
					flag=false;break;
				}
			}
			if(flag)	v.push_back(e[i][j]),bk[i][j]=true,bk[j][i]=true;
		}
	}
//	cout<<v.size()<<endl;
	if((int)v.size()==n-1){
		printf("Yes\n");
		sort(v.begin(),v.end());
		for(int i=0;i<n-1;i++){
			printf("%lld\n",v[i]);
		}
	}
	else{
		printf("No\n");
	}
}

上一题