POJ 1182 食物链(带权并查集)

来源:互联网 发布:淘宝真皮女装退货率 编辑:程序博客网 时间:2024/05/22 07:47

花了将近一天的时间,终于理解了这道题目的含义。

比较难理解的是将两个father[x]和father[y]合在一起的时候怎么判断Rank[father[y]];

还有路径压缩的时候,也要更Rank。

#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int maxn = 5e4+5;int father[maxn],Rank[maxn],n,m;int query(int x) {    if(x != father[x]) {        int per = father[x];        father[x] = query(father[x]);        Rank[x] = (Rank[x] + Rank[per]) % 3;    }    return father[x];}int main() {    freopen("haha.txt","r",stdin);    scanf("%d%d",&n,&m);         for(int i = 0;i <= n;i++) {            father[i] = i;            Rank[i] = 0;        }        int d,x,y,ans = 0;        for(int i = 1;i <= m;i++) {            scanf("%d%d%d",&d,&x,&y);            if(x > n || y > n) {                ans++;                continue;            }            if(query(x) == query(y)) {                //printf("%d-%d-%d\n",Rank[x],Rank[y],Rank[y]-Rank[x]);                if(d == 1 && Rank[x] != Rank[y]) ans++;                if(d == 2 && ((Rank[y] - Rank[x] != 1) && (Rank[y] - Rank[x] != -2))){                    ans++;                }            }            else {                int a = query(x);                int b = query(y);                if(d == 2) {                    father[b] = a;                    Rank[b] = (Rank[x] - Rank[y] + 4) % 3; //   fy 与 y 的关系是 3-r[y], x 与 y 的关系是 d-1 (因为确定是不同类,才联合的), x 与 fx 关系是 r[x],模 3 是因为只有三种关系。所以又上面的一点所推出的定理可以证明 fx 与 fy 的关系是: (r[x]-r[y]+(d-1)+3)%3                }                if(d == 1) {                    father[b] = a;                    Rank[b] = (Rank[x] - Rank[y] + 3) % 3;                }            }            //printf("%d\n",ans);        }        printf("%d\n",ans);    return 0;}



0 0
原创粉丝点击