#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define IOS std::ios::sync_with_stdio(0) , cin.tie(0);
using namespace std;
const int maxn = 5e4 + 5;
int fa[maxn], Rank[maxn], num[maxn], N, M, cnt, n; //Rank数组表示x到fa[x]的奇偶性
struct Edge { //结构体存区间顺序,va表示奇数还是偶数
int x, y, va;
} edge[maxn];
int search(int x) { //二分快速查找x在num数组的顺序
int left = 0, right = n;
while (left + 1 < right) {
int mid = (left + right) >> 1;
if (num[mid] == x)
return mid;
if (num[mid] < x)
left = mid;
else
right = mid;
}
if (num[left] == x)
return left;
else
return right;
}
int query(int x) { //路径压缩 带权并查集
if (x != fa[x]) {
int per = fa[x];
fa[x] = query( fa[x] );
Rank[x] = (Rank[x] + Rank[per]) % 2;
}
return fa[x];
}
void inti() {
for (int i = 1; i <= cnt; ++i) {
fa[i] = i;
// Rank[i] = 0;
}
}
int main() {
// std::ios::sync_with_stdio(0), cin.tie(0),cout.tie(0);
cin >> N >> M;
char str[20];
cnt = 0;
for (int i = 0; i < M; i++) {
cin >> edge[i].x >> edge[i].y >> str;
edge[i].x--; //连续
if (str[0] == 'e')
edge[i].va = 0; //odd even 处理
else
edge[i].va = 1;
num[cnt++] = edge[i].x; //存入num数组离散化
num[cnt++] = edge[i].y; //
}
inti();
sort(num, num + cnt);
n = unique(num, num + cnt) - num; //unique函数的作用是去重,并且返回数组的迭代器,再减去数组num的地址就是新数组的长度
int i;
for (i = 0; i < M; i++) {
int pa = search(edge[i].x);
int pb = search(edge[i].y);
int X = query(pa);
int Y = query(pb);
if (X == Y) { //
if ( (Rank[pa] + Rank[pb] + 2) % 2 != edge[i].va) { //两种路径的奇偶性必须相等
cout << i;
return 0;
}
}
else {
fa[Y] = X; //在x,y中直接连一条线的权
Rank[Y] = (Rank[pa] - Rank[pb] + edge[i].va +2 ) % 2; //合并
}
}
cout << M;
return 0;
}
并查集/带权并查集/离散化
最新推荐文章于 2023-08-28 21:32:14 发布