题意:对于一个整数序列,每次指令为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 #include7 #include 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 else56 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\n", ans);65 }66 return 0;67 }