[POJ - 1733]
每次给出一个区间内1个数的奇偶性,判断什么时候与之前的奇偶性相矛盾
将区间两个端点取出,离散化之后作为并查集中的点,赋予两点边权为奇偶性
在压缩路径的时候,类似于距离一样去思考即可
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
using namespace std;
const int maxn = 1e5+5;
struct Node{
int l,r,w;
}node[maxn];
vector<int> vec;
int getID(int x){
return lower_bound(vec.begin(),vec.end(),x) - vec.begin();
}
int pre[maxn],r[maxn];
void init(int n){
for(int i = 0; i <= maxn; ++i) pre[i] = i,r[i] = 0;
}
int Findpre(int x){
if(pre[x] == x) return x;
int tmp = pre[x];
pre[x] = Findpre(pre[x]);
r[x] = (r[x] + r[tmp])%2;
return pre[x];
}
int ans;
bool Union(int x,int y,int w){
int fx = Findpre(x),fy = Findpre(y);
if(fx!=fy){
pre[fy] = fx;
r[fy] = (r[x] + r[y] + w)%2;
}
else if((r[y] + r[x])%2!=w)
return false;
return true;
}
int main()
{
int n,m; cin >> n >> m; init(n);
for(int i = 0; i < m; ++i){
Node &nn = node[i];
cin >> nn.l >> nn.r; string str; cin >> str;
if(str=="even") nn.w = 0; else nn.w = 1;
vec.push_back(nn.l-1); vec.push_back(nn.r);
}
sort(vec.begin(),vec.end());
vec.erase(unique(vec.begin(),vec.end()),vec.end());
ans = m;
for(int i = 0; i < m; ++i){
Node & nn = node[i];;
if(!Union(getID(nn.l-1),getID(nn.r),nn.w)){
ans = i;
break;
}
}
cout << ans << endl;
return 0;
}
[HDU - 3038] 跟上一题差不多的,只是点与点之间的关系变成了距离,因此关系转换的表达式要修改一下,这里可以理解成两个向量之间的距离
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = 2e5+5;
int pre[maxn];
int r[maxn];
void init(int n){
for(int i = 0; i < maxn; ++i) pre[i] = i,r[i] = 0;
memset(r,0,sizeof(r));
}
// 带权并查集的路径压缩,合并
int Findpre(int x){
if(pre[x]==x) return x;
int tmp = pre[x];
pre[x] = Findpre(pre[x]);
r[x] += r[tmp];
return pre[x];
}
int cnt = 0;
void Union(int x,int y,int s){
int fx = Findpre(x),fy = Findpre(y);
if(fx!=fy){
pre[fy] = fx;
r[fy] = r[x] - r[y] + s;
}
else{
if(r[y] - r[x]!=s)
cnt++;
}
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n,m;
while(cin >> n >> m){
init(n); cnt = 0;
for(int i = 0; i < m; ++i){
int l,r,w; cin >> l >> r >> w;
Union(l-1,r,w);
}
cout << cnt << endl;
}
return 0;
}