Problem:
A吃B,B吃C,C吃A,给了一系列的关系,判断两个东西的关系是否和已给的关系冲突。
Solution:
将关系当做一个权加入并查集当中,相关关系在一个树上。
具体解法这篇链接讲的很清楚,但是它的代码我觉得还有很大的改进空间,比如还可以提炼出举一反三的模板,代码可读性还可以增加,主函数当中的逻辑冗余,所以我在看懂了这篇博客之后自己又进行了修改和总结。
参考链接:http://blog.csdn.net/niushuai666/article/details/6981689
note:
1. 一定要记得并查集的初始化。
#include<cstdio>
#include<iostream>
#include<sstream>
#include<cstdlib>
#include<cmath>
#include<cctype>
#include<string>
#include<cstring>
#include<algorithm>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<ctime>
#include<vector>
#include<fstream>
#include<list>
#include<iomanip>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(s) memset(s,0,sizeof(s))
const double PI = 3.141592653589;
const int INF = 0x3fffffff;
template <typename Type>
class DisjointSet {
struct node {
int parent_;
Type relation_; //parent -> this
node() {
relation_ = 0;
}
};
vector<node> nodes;
vector<int> parents;
public:
bool is_relation_;
DisjointSet(int number_nodes, bool is_relation = false) {
is_relation_ = is_relation;
if(is_relation_) {
nodes.resize(number_nodes+1);
for(int i = 0; i <= number_nodes; ++i)
nodes[i].parent_ = i;
} else {
parents.resize(number_nodes+1);
for(int i = 0; i <= number_nodes; ++i)
parents[i] = i;
}
}
int find(int x) {
if(is_relation_) {
if(nodes[x].parent_ != x) {
int xparent = nodes[x].parent_; // x's old parent
nodes[x].parent_ = find(nodes[x].parent_);
nodes[x].relation_ = nodes[x].relation_ + nodes[xparent].relation_;
}
return nodes[x].parent_;
} else {
if(parents[x] != x)
parents[x] = find(parents[x]);
return parents[x];
}
}
Type get_relation(int x) {
return nodes[x].relation_;
}
void merge(int x, int y) {
parents[find(y)] = find(x);
}
void merge(int x, int y, Type relation) {
// relation: x->y
int yparent = find(y);
nodes[yparent].parent_ = find(x);
nodes[yparent].relation_ = nodes[x].relation_ + relation - nodes[y].relation_;
}
};
int main() {
// freopen("/Users/really/Documents/code/input","r",stdin);
int n, k;
scanf("%d%d", &n, &k);
DisjointSet<int> ds(n, true);
int d, x, y, ans = 0;
for(int i = 0; i < k; i++) {
scanf("%d%d%d", &d, &x, &y);
if(x > n || y > n)
ans++;
else if(d == 2 && x == y)
ans++;
else if(ds.find(x) == ds.find(y)) {
if(d-1 != ((ds.get_relation(y)-ds.get_relation(x))%3 + 3)%3)
ans++;
}
else {
ds.merge(x, y, d-1);
}
}
printf("%d\n", ans);
return 0;
}