P1955 [NOI2015] 程序自动分析
解题思路
输入的数据有满足约束和不满足约束,很明显我们能解决的是等于的情况,用并查集直接将相等的两个变量合并起来,并且我们很明显能发现是否满足条件和判断的顺序是无关的,所以我们可以先将相等的变量进行合并然后再判断后面不相等的是否满足即可(换句话说我们通过排序,先处理相等的变量,再处理),注意的是这里的i,j可能很大,所以我们不能直接开数组,于是我用的map表示的fa数组
Code
#include<bits/stdc++.h>
using namespace std;
unordered_map<int,int> fa;
const int N = 1e6+10;
struct Node {
int a,b,c;
}V[N];
bool cmp(Node a,Node b) {
return a.c > b.c;
}
int find(int x) {
int t = x;
while(t != fa[t]) t = fa[t];
while(x != fa[x]) {
int temp = fa[x];
fa[x] = t;
x = temp;
}
return x;
}
void merge(int a,int b) {
a = find(a);
b = find(b);
if(a != b) {
fa[b] = a;
}
}
int main()
{
int t,n;
scanf("%d",&t);
while(t--) {
cin>>n;
fa.clear();
for(int i = 1;i <= n; ++i) {
scanf("%d%d%d",&V[i].a,&V[i].b,&V[i].c);
fa[V[i].a] = V[i].a;
fa[V[i].b] = V[i].b;
}
sort(V+1,V+n+1,cmp);
bool fg = true;
for(int i = 1;i <= n; ++i) {
if(V[i].c) {
merge(V[i].a,V[i].b);
}
else {
V[i].a = find(V[i].a);
V[i].b = find(V[i].b);
if(V[i].a == V[i].b) {
fg = false;
break;
}
}
}
if(fg) puts("YES");
else puts("NO");
}
return 0;
}