#luogu整理 P2024 食物链 重点在于正确构造出要求的形式,前提是能看出来这个用并查集

链接

这应该是并查集挺难的题目了然后我上课听老师讲的听清楚,我就心想:

这么简单的题我要切了他!!

于是我按照自己记录的思路写了一下午就成了这个样子

#luogu整理 P2024 食物链
重点在于正确构造出要求的形式,前提是能看出来这个用并查集

对不起,是我太菜了

于是呢我就去看了题解,整个修改代码的难点在于我思路和题解完全不一样???

正确思路:

链接

//
//  main.cpp
//  P2024
//
//  Created by 曹宇琮 on 2020/1/19.
//  Copyright © 2020 曹宇琮. All rights reserved.
//

//#include <iostream>
//#include <cstdio>
//#include <algorithm>
//#include <cstdio>
//#include <cstring>
//using namespace std;
//int n,k;int fa[150099],dep[150099],vis[150099];
//int cnt = 0;
//
//int getfa(int x){
//    return fa[x] == x ? x : getfa(fa[x]);
//}
//
//void add_point(int x,int y,int tmp){//把x合并到y的集合中
//    int was = vis[x];
//    vis[x] = vis[y];
//    fa[getfa(x)] = fa[getfa(y)];
//    dep[x] = (dep[y] + tmp) % 3;
//    for(int i = 1;i <= n; i++)
//        if(vis[i] == was){
//            dep[i] = (dep[y] + dep[i] + tmp) % 3;
//        }
//}
//
//int main(){
//    memset(dep,0,sizeof dep);
//    cin >> n >> k;
//    for(int i = 1;i <= n; i++) fa[i] = i;
//    int a,x,y;
//    int ans = 0;
//    for(int i = 1;i <= k; i++){
//        cin >> a >> x >> y;
//        if(x > n || y > n){ans++;continue;}
//        if(a == 2 && y == x) {ans++;continue;}
//        if(a == 1 && y == x) {continue;}
//        if(getfa(x) == x && getfa(y) == y && getfa(x) != getfa(y)){
//            cnt++;
//            vis[x] = cnt;
//        }
//        if(a == 1){
//            if(vis[x] != vis[y]&& getfa(x) != getfa(y)){
//                add_point(x,y,0);
//            }else if(vis[y] != vis[x] && getfa(x) != getfa(y)){
//                add_point(y,x,0);
//            }else{
//                if(vis[x] != vis[y]){ans++;continue;}
//                ans += (int)(dep[x] != dep[y]);
////                if((dep[x] != dep[y]))
////                   cout << i << endl;
//            }
//        }else{
//            if(vis[x] != vis[y] && getfa(x) != getfa(y)){
//                add_point(x,y,1);
//            }else if(vis[y] != vis[x] && getfa(x) != getfa(y)){
//                add_point(y,x,2);
//            }else{
//                if(vis[y] != vis[x]){ans++;continue;}
//                if(dep[x] < dep[y]) swap(x,y);
//                ans += !(dep[x] == (dep[y] + 1) % 3 || dep[x] == (dep[y] + 2) % 3) ? 1:0;
////                if(!(dep[x] == (dep[y] + 1) % 3 || dep[x] == (dep[y] + 2) % 3)) cout << 0 << endl;
//            }
//        }
//    }
//
//    cout << ans << endl;
//    return 0;
//}//我坚信我写的没有任何问题,只是有点困而已(真的哈哈哈哈哈哈哈哈)

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int n,k,ans;
int fa[100005 * 3];

int getfa(int x){
    return fa[x] == x ? x : fa[x] = getfa(fa[x]);//注意并查集的优化!!!
}

int main(){
    cin >> n >> k;
    for(int i = 0;i < 100005 * 3; i++) fa[i] = i;
    int a,x,y;
    for(int i = 1;i <= k; i++){
        cin >> a >> x >> y;
        if(x > n || y > n){ans++;continue;}
        if(a == 2 && y == x) {ans++;continue;}
        if(a == 1 && y == x) {continue;}
        if(a == 1){
            if(getfa(x) == getfa(y + n) || getfa(y) == getfa(x + n)){ans++;continue;}//如果x → y或y→x,就不行
            fa[getfa(x)] = getfa(y);
            fa[getfa(x + n)] = getfa(y + n);
            fa[getfa(x + n + n)] = getfa(y + n + n);//自己集合中的是同一种小动物
        }else{
            if(getfa(x) == getfa(y) || getfa(x + n) == getfa(y)){ans++;continue;}//如果xy是同一种小动物或者y → x就不行
            fa[getfa(x)] = getfa(y + n);
            fa[getfa(x + n)] = getfa(y + n + n);
            fa[getfa(x + n + n)] = getfa(y);//注意并查集的优化!!!!
        }
    }
    cout << ans << endl;
    return 0;//lcez_cyc
}

看完题解感觉挺简单的