题意:给你一个无向有权的图,图上的点被分成了几类,对于同类的点你需要判断它们之间相互的最短距离是不是0.满足这个条件之后要输出的是类与类之间的最短距离的矩阵。点给到10^5这么多,判断同类的点显然不能跑最短路,所以直接的方法必然是并查集,对边为0的点做一次并查集,对同类的点判一下find(x)==find(y)就可以了。 然后就是将同类的点抽象出一个新的点,这个时候只有500个点,然后就可以跑一下floyd了。 题意有坑的地方,所以没有AC比赛的时候。 这题倒是很好的练了一下基础的内容并查集和floyd。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 |
#pragma warning(disable:4996) #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #include<cmath> #include<queue> #define ll long long #define maxn 100500 #define inf 0x3f3f3f3f using
namespace std; vector< int > ZG[maxn]; int
type[550]; int
sum[550]; int
n, m, k; int
fa[maxn]; int
find( int
x) { return
fa[x] == x ? fa[x] : fa[x] = find(fa[x]); } bool
deterMine( int
index) { int
sid = sum[index - 1]; for
( int i = sid + 1; i <= sid + type[index]; i++){ if
(find(sid + 1) != find(i)) return
false ; } return
true ; } int
dist[550][550]; int
main() { while
(cin >> n >> m >> k) { sum[0] = 0; for
( int i = 1; i <= k; i++){ scanf ( "%d" , &type[i]); sum[i] = sum[i - 1] + type[i]; } int
ui, vi, wi; memset (dist, 0x3f, sizeof (dist)); for
( int i = 0; i <= n; i++) fa[i] = i; for
( int i = 0; i <= k; i++) { dist[i][i] = 0; } for
( int i = 0; i < m; i++){ scanf ( "%d%d%d" , &ui, &vi, &wi); int
ut = lower_bound(sum, sum + 1 + k, ui) - sum; int
vt = lower_bound(sum, sum + 1 + k, vi) - sum; dist[ut][vt] = min(dist[ut][vt], wi); dist[vt][ut] = min(dist[vt][ut], wi); if
(wi == 0) { if
(find(ui) != find(vi)){ fa[find(ui)] = fa[find(vi)]; } } } for
( int i = 1; i <= n; i++) find(i); bool
flag = true ; for
( int i = 1; i <= k; i++){ if
(deterMine(i) == false ){ flag = false ; } } if
(!flag) { puts ( "No" ); continue ; } puts ( "Yes" ); for
( int kk = 1; kk <= k; kk++){ for
( int i = 1; i <= k; i++){ for
( int j = 1; j <= k; j++){ if
(dist[i][kk] + dist[kk][j] < dist[i][j]){ dist[i][j] = dist[i][kk] + dist[kk][j]; } } } } for
( int i = 1; i <= k; i++){ for
( int j = 1; j <= k; j++){ if
(j != 1) printf ( " " ); if
(dist[i][j] < inf) printf ( "%d" , dist[i][j]); else
printf ( "%d" , -1); } puts ( "" ); } } return
0; } |
Codeforces400D Dima and Bacteria,布布扣,bubuko.com
Codeforces400D Dima and Bacteria
原文:http://www.cnblogs.com/chanme/p/3583728.html