链接:https://ac.nowcoder.com/acm/contest/3007/I
来源:牛客网
题目描述
小 Q 所在的国家有 N 个城市,城市间由 N-1 条双向道路连接,任意一对城市都是互通的。
每条道路有一个长度,自然,小 Q 的导航系统能显示每对城市间的最短距离。
但是小 Q 对这个系统并不太放心,于是他向你求助:
给定每对城市间的最短距离,你要判断距离表是否一定有误。
如果这张距离表是自洽的,那么请你按升序依次给出每条道路的长度。
对于全部的数据,1≤N≤500,输入的所有数字都是不超过 10 9 的非负整数。
输入描述:
第一行一个数字 N
接下来 N 行,每行 N 个正整数
第 i 行第 j 列的数字表示城市 i 和城市 j 间的最短距离
保证第 i 行第 i 列的数字为 0
输出描述:
第一行,一个字符串
如果距离表没有问题,输出“Yes”
并在接下来的 N-1 行从小到大给出每条道路的长度
否则输出“No”即可
示例2
输出
复制No
题解
跑一遍MST得出道路长度长,跑一遍Floyd处理出任意两点间距离并与导航给出的距离对比
CODE
1 #include <bits/stdc++.h> 2 #define dbg(x) cout << #x << "=" << x << endl 3 #define eps 1e-8 4 #define pi acos(-1.0) 5 6 using namespace std; 7 typedef long long LL; 8 9 template<class T>inline void read(T &res) 10 { 11 char c;T flag=1; 12 while((c=getchar())<'0'||c>'9')if(c=='-')flag=-1;res=c-'0'; 13 while((c=getchar())>='0'&&c<='9')res=res*10+c-'0';res*=flag; 14 } 15 16 namespace _buff { 17 const size_t BUFF = 1 << 19; 18 char ibuf[BUFF], *ib = ibuf, *ie = ibuf; 19 char getc() { 20 if (ib == ie) { 21 ib = ibuf; 22 ie = ibuf + fread(ibuf, 1, BUFF, stdin); 23 } 24 return ib == ie ? -1 : *ib++; 25 } 26 } 27 28 int qread() { 29 using namespace _buff; 30 int ret = 0; 31 bool pos = true; 32 char c = getc(); 33 for (; (c < '0' || c > '9') && c != '-'; c = getc()) { 34 assert(~c); 35 } 36 if (c == '-') { 37 pos = false; 38 c = getc(); 39 } 40 for (; c >= '0' && c <= '9'; c = getc()) { 41 ret = (ret << 3) + (ret << 1) + (c ^ 48); 42 } 43 return pos ? ret : -ret; 44 } 45 46 const int maxn = 507; 47 48 struct node 49 { 50 int u,v,w; 51 }e[maxn*maxn]; 52 53 int fa[maxn]; 54 LL g[maxn][maxn]; 55 LL dis[maxn][maxn]; 56 57 int tot[maxn]; 58 59 int fid(int x) 60 { 61 return fa[x]==x ? x : fa[x] = fid(fa[x]); 62 } 63 64 bool cmp(node a,node b) 65 { 66 return a.w < b.w; 67 } 68 69 int main() 70 { 71 int n; 72 int num=0,x,sum=0; 73 read(n); 74 for(int i = 1; i <= n; ++i) { 75 for(int j = 1; j <= n; ++j) { 76 read(x); 77 g[i][j] = x; 78 if(i != j) 79 { 80 e[++num].w=x; 81 e[num].u=i; 82 e[num].v=j; 83 } 84 } 85 } 86 sort(e+1,e+num+1,cmp); 87 for(int i = 1; i <= n; ++i) { 88 for(int j = 1; j <= n; ++j) { 89 if(i == j) dis[i][j] = 0; 90 else dis[i][j] = 1e18; 91 } 92 } 93 for(int i = 1; i <= n; ++i) { 94 fa[i] = i; 95 } 96 int u,v; 97 for(int i = 1;i <= num; ++i) { 98 u = e[i].u; 99 v = e[i].v; 100 if(fid(u)!=fid(v)) 101 { 102 dis[u][v] = dis[v][u] = e[i].w; 103 tot[++sum] = e[i].w; 104 fa[fa[u]] = fa[v]; 105 } 106 } 107 for(int k = 1; k <= n; ++k) { 108 for(int i = 1; i <= n; ++i) { 109 for(int j = 1; j <= n; ++j) { 110 dis[i][j] = min(dis[i][j], dis[i][k]+dis[k][j]); 111 } 112 } 113 } 114 for(int i = 1; i <= n; ++i) { 115 for(int j = 1; j <= n; ++j) { 116 if(dis[i][j] != g[i][j]) { 117 printf("No"); 118 return 0; 119 } 120 } 121 } 122 printf("Yes\n"); 123 sort(tot+1,tot+n); 124 for(int i = 1; i < n; ++i) { 125 printf("%d\n",tot[i]); 126 } 127 }