题目链接
https://www.acwing.com/problem/content/239/
思路
看了《算法竞赛进阶指南》和别人的题解才明白这题需要用离散化处理10的9次方的范围,本题需要将所有待验证的组,即第三个值为0的边,全部先存放起来,这里采用pair<int,int>类型的vector存放。关键是离散化的操作,主要步骤就是存放输入进来的数、利用sort排序,再利用unique去重计数,最后利用lower_bound查找到对应的数,除了离散化部分,剩余的都是并查集的传统操作。
c++代码
#include <bits/stdc++.h>
#define x first
#define y second
using namespace std;
const int N = 2e6 + 5;
vector<pair<int, int> > a, b;
int t, m, n, p[N], x, y, c, id[N];
int find(int x)
{
if(x!=p[x]) p[x]=find(p[x]);
return p[x];
}
int getId(int x)
{
return lower_bound(id+1,id+1+n,x)-id;
}
void solve()
{
for(int i=1;i<=n;i++) p[i]=i;
for(int i=0;i<a.size();i++)
{
int x=getId(a[i].x);
int y=getId(a[i].y);
int fx=find(x);
int fy=find(y);
p[fx]=fy;
}
for(int i=0;i<b.size();i++)
{
int x=getId(b[i].x);
int y=getId(b[i].y);
int fx=find(x);
int fy=find(y);
if(fx==fy)
{
printf("NO\n");
return;
}
}
printf("YES\n");
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
a.clear();
b.clear();
n=0;
scanf("%d",&m);
for(int i=1;i<=m;i++)
{
scanf("%d%d%d",&x,&y,&c);
if(c==1)
{
a.push_back(make_pair(x,y));
}
else
{
b.push_back(make_pair(x,y));
}
id[n]=x;
n++;
id[n]=y;
n++;
}
sort(id+1,id+1+n);
n = unique(id + 1, id + 1 + n) - id - 1;
solve();
}
return 0;
}