食物链

来源:互联网 发布:vb.net调用matlab 编辑:程序博客网 时间:2024/04/27 07:23

很经典的一道关系型并查集题目

#include <cstring>#include <cstdio>#include <iostream>using namespace std;#define MAX 50001int father[MAX],rank[MAX];void _Set(int x){    for(int i = 1;i <= x;i++){        father[i] = i;        rank[i] = 0;    }}int _Find(int x){int y,temp,dis,len;y = x,len = 0;while(y != father[y]){len = (len + rank[y]) % 3;y = father[y];}while(x != father[x]){temp = father[x];dis = rank[x];rank[x] = len % 3;father[x] = y;len =(len - dis  + 3) % 3;x = temp;}return y;}void _Union(int x,int y,int d){    int xx = _Find(x);    int yy = _Find(y);    int len = d - 1;    father[yy] = xx;    rank[yy] = (rank[x] - rank[y] + len + 3) % 3;}int main(){    int n,k,d,x,y;    scanf("%d%d",&n,&k);    _Set(n);    int sum = 0;    for(int i =0;i < k;i++){        scanf("%d%d%d",&d,&x,&y);        if(x > n || y > n || ( d == 2 && x == y)){            sum++;            continue;        }        int rx = _Find(x);        int ry = _Find(y);        if(rx == ry){            if(d == 1 && rank[x] != rank[y]){                sum++;                continue;            }            if(d == 2 && (3 - rank[x] + rank[y] ) % 3 != d - 1){               sum++;               continue;            }        }        else _Union(x,y,d);    }    printf("%d\n",sum);    return 0;}


0 0
原创粉丝点击