Skip to content

M27306: 植物观察

disjoint set, bfs, http://cs101.openjudge.cn/practice/27306/

思路:典型二分图判断

cpp
#include <iostream>
#include <vector>
using namespace std;

const int MAX_N = 105;  
int parent[MAX_N];     
int relation[MAX_N];    
void init(int n) {
    for (int i = 0; i < n; ++i) {
        parent[i] = i;  
        relation[i] = 0; 
    }
}
int find(int x) {
    if (parent[x] != x) {
        int origin_parent = parent[x];
        parent[x] = find(parent[x]); 
        relation[x] ^= relation[origin_parent];
    }
    return parent[x];
}

int main() {
    int n, m;
    cin >> n >> m;
    init(n);
    bool possible = true;  
    for (int i = 0; i < m; ++i) {
        int a, b, op;
        cin >> a >> b >> op;
        int root_a = find(a);
        int root_b = find(b);
        if (root_a == root_b) {
            if ((relation[a] ^ relation[b]) != op) {
                possible = false;
            }
        } else {
            parent[root_b] = root_a;
            relation[root_b] = relation[a] ^ relation[b] ^ op;
        }
    }
    cout << (possible ? "YES" : "NO") << endl;
    return 0;
}

思路:和LC886 可能的二分法一样,唯一不同的就是不仅要求某两个不在一组,还要求某两个在一组。

cpp
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
int find(vector<int>& parent,int i){
    if(i!=parent[i]){
        return find(parent,parent[i]);
    }
    return i;
}
void Union(vector<int>& parent,int i,int j){
    parent[find(parent,i)]=find(parent,j);
}
int main(){
    int n,m;
    cin>>n>>m;
    int flag=1;
    vector<vector<int>>different(n);
    vector<int>parent(n);
    for(int i=0;i<n;i++){
        parent[i]=i;
    }
    for(int i=0;i<m;i++){
        int p,q,r;
        cin>>p>>q>>r;
        if(r==0){
            Union(parent,p,q);
        }
        else{
            different[p].push_back(q);
            different[q].push_back(p);
        }
    }
    for(int i=0;i<n;i++){
        if(different[i].size()==0) 
        {continue;}
        int p=find(parent,i);
        int q=find(parent,different[i][0]);
        if(q==p)
        {
            flag=0;
            break;
        }
        if(different[i].size()>=2)
        {
            for(int j=1;j<different[i].size();j++)
            {
                if(find(parent,i)==find(parent,different[i][j])) {
                    flag=0;
                    break;
                }
                Union(parent,different[i][0],different[i][j]);
            } 
            if(flag==0) break;  
        }
    }
    if (flag==1){
        cout<<"YES";
    }
    else{
        cout<<"NO";
    }
    return 0;
}