HDU 3038 How Many Answers Are Wrong

题意:对于一个整数序列,每次指令为a b c,表示序列中从第a项加到第b项的和为c。若某条指令与前面指令所传达的信息矛盾,则视为该指令错误,否则视为该指令正确。给出一串指令,问错误指令的数量为多少。

解法:类似POJ 1182 食物链。用并查集做,每个节点有两个参数,比如对于节点x,一个是f,表示其根节点的编号;另一个是r,表示前x项之和减去前x.f项之和的差值。然后判定就好了。

tag:并查集

 1 /*
 2  * Author:  Plumrain
 3  * Created Time:  2013-11-28 08:32
 4  * File Name: DS-HDU-3038.cpp
 5  */
 6 #include <iostream>
 7 #include <cstdio>
 8 
 9 using namespace std;
10 
11 struct node{
12     int f, r;
13 };
14 
15 int n, m, ans;
16 node a[200005];
17 
18 int find(int x)
19 {
20     if (x != a[x].f){
21         int y = a[x].f;
22         a[x].f = find(a[x].f);
23         a[x].r = a[x].r + a[y].r;
24     }
25     return a[x].f;
26 }
27 
28 void merge(int ta, int tb, int s, int fa, int fb)
29 {
30     a[fa].f = fb;
31     a[fa].r = a[tb].r - a[ta].r - s;
32 }
33 
34 bool ok(int ta, int tb, int s, int fa, int fb)
35 {
36     return s == (a[tb].r - a[ta].r); 
37 }
38 
39 void init()
40 {
41     ans = 0;
42     for (int i = 0; i <= n; ++ i){
43         a[i].f = i;
44         a[i].r = 0;
45     }
46 
47     int ta, tb, s;
48     for (int i = 0; i < m; ++ i){
49         scanf ("%d%d%d", &ta, &tb, &s);
50         -- ta;
51         
52         int t1 = find(ta), t2 = find(tb);
53         if (t1 != t2)
54             merge(ta, tb, s, t1, t2);
55         else
56             if (!ok(ta, tb, s, t1, t2)) ++ ans;
57     }
58 }
59 
60 int main()
61 {
62     while (scanf ("%d%d", &n, &m) != EOF){
63         init();
64         printf ("%d
", ans);
65     }
66     return 0;
67 }
View Code
------------------------------------------------------------------
现在的你,在干什么呢?
你是不是还记得,你说你想成为岩哥那样的人。
原文地址:https://www.cnblogs.com/plumrain/p/HDU_3038.html