POJ1182-食物链 【权值并查集】

    xiaoxiao2024-11-04  79

    动物王国中有三类动物A,B,C,这三类动物的食物链构成了有趣的环形。A吃B, B吃C,C吃A。  现有N个动物,以1-N编号。每个动物都是A,B,C中的一种,但是我们并不知道它到底是哪一种。 有人用两种说法对这N个动物所构成的食物链关系进行描述:  第一种说法是"1 X Y",表示X和Y是同类。  第二种说法是"2 X Y",表示X吃Y。  此人对N个动物,用上述两种说法,一句接一句地说出K句话,这K句话有的是真的,有的是假的。当一句话满足下列三条之一时,这句话就是假话,否则就是真话。  1) 当前的话与前面的某些真的话冲突,就是假话;  2) 当前的话中X或Y比N大,就是假话;  3) 当前的话表示X吃X,就是假话。  你的任务是根据给定的N(1 <= N <= 50,000)和K句话(0 <= K <= 100,000),输出假话的总数。 

    Input

    第一行是两个整数N和K,以一个空格分隔。  以下K行每行是三个正整数 D,X,Y,两数之间用一个空格隔开,其中D表示说法的种类。  若D=1,则表示X和Y是同类。  若D=2,则表示X吃Y。

    Output

    只有一个整数,表示假话的数目。

    思路:r[i]数组表示i结点跟根节点的关系,(a, b) ,0表示同类,1表示a被b吃,2表示a吃b,那么如何确定两个结点间的关系呢,

    通过推导不难发现,当(r[a] + 1) % 3 == r[b] 时表示a吃b。

    定义 :fx 为 x 的根点, fy 为 y 的根节点

               合并时,如果把 y 树合并到 x 树中

               如何求 fy 对 fx 的r[]关系?

               fy 对 y 的关系为 3-r[y]

               y  对 x 的关系为 d-1

               x  对 fx 的关系为 r[x]

               所以 fy 对 fx 的关系是(3-r[y] + d-1 + r[x])%3

    这里有篇博客讲的很棒打开链接

    #include<ctime> #include<vector> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; typedef long long ll; #define lson l, mid, rt << 1 #define rson mid + 1, r, rt << 1 | 1 const int maxn = 5e4 + 10; const int inf = 0x3f3f3f3f; int pre[maxn], r[maxn]; //父亲、权值(表示与根节点的关系) void init(int n) { for(int i = 0; i <= n; ++i) { pre[i] = i; r[i] = 0; } } int Find(int x) { if(x == pre[x]) return x; int tmp = pre[x]; pre[x] = Find(pre[x]);//递归找根节点 r[x] = (r[x] + r[tmp]) % 3; //回溯时从根节点向上更新父子结点间关系 return pre[x]; } void join(int x, int y, int d) //合并 { int a = Find(x); int b = Find(y); pre[b] = a; //因为x吃y,合并时以x为根节点 r[b] = (3 - r[y] + d - 1 + r[x]) % 3; } int main() { int n, k; scanf("%d%d", &n, &k); init(n); int ans = 0; for(int i = 1; i <= k; ++i) { int d, x, y; scanf("%d%d%d", &d, &x, &y); if(x > n || y > n || (d == 2 && x == y)) ++ans; else if(Find(x) == Find(y))//之前有关系 { if(d == 1 && r[x] != r[y]) ++ans; if(d == 2 && (r[x] + 1) % 3 != r[y]) ++ans; } else join(x, y, d); } printf("%d\n", ans); return 0; }

     

    最新回复(0)