思路跟 LA 6187 完全一样。
我是乍一看没反应过来这是个并查集,知道之后就好做了。
d[i]代表节点 i 到根节点的距离,即每次的sum。
1 #include <cstdio> 2 #include <cstring> 3 #include <cstdlib> 4 5 const int MAXN = 200010; 6 7 int N, Q; 8 int p[MAXN]; 9 int d[MAXN]; 10 11 int FindSet( int x ) 12 { 13 if ( p[x] == x ) return x; 14 int root = FindSet( p[x] ); 15 d[x] += d[ p[x] ]; 16 return p[x] = root; 17 } 18 19 int main() 20 { 21 while ( ~scanf( "%d%d", &N, &Q ) ) 22 { 23 for ( int i = 0; i <= N; ++i ) 24 { 25 d[i] = 0; 26 p[i] = i; 27 } 28 29 int cnt = 0; 30 while ( Q-- ) 31 { 32 int a, b, sum; 33 scanf( "%d%d%d", &a, &b, &sum ); 34 --a; 35 int u = FindSet( a ); 36 int v = FindSet( b ); 37 if ( u == v ) 38 { 39 if ( sum != d[b] - d[a] ) 40 ++cnt; 41 } 42 else 43 { 44 p[v] = u; 45 d[v] = d[a] - d[b] + sum; 46 } 47 } 48 49 printf( "%d ", cnt ); 50 } 51 return 0; 52 }