现在的位置: 首页 > 综合 > 正文

食物链

2018年04月21日 ⁄ 综合 ⁄ 共 838字 ⁄ 字号 评论关闭

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

#include <cstring>
#include <cstdio>
#include <iostream>
using namespace std;
#define MAX 50001
int 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;
}
【上篇】
【下篇】

抱歉!评论已关闭.