P1955 [NOI2015] 程序自动分析 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
先排序,把所有e==1的操作放在前面,然后再进行e==0的操作。在进行e==1的操作的时候,我们只要把它约束的两个变量放在同一个集合里面即可。在e==0,即存在一条不相等的约束条件,对于它约束的两个变量,如果在一个集合里面,那就不可能满足!如不相等的约束条件都满足,那就YES。
#include
#define maxn 100001
using namespace std;
int fa[maxn];
struct node{
int x,y,z;
}a[maxn];
bool cmp(node a,node b){
return a.z>b.z;
}
int Find(int x){
return x==fa[x] ? x : fa[x]=Find(fa[x]);
}
int main(){
int n,T;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
//初始化
for(int i=1;i<=n;i++) fa[i]=i;
memset(a,0,sizeof(a));
//读入数据
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
}
sort(a+1,a+1+n,cmp);
bool flag=0;
for(int i=1;i<=n;i++){
int fx=Find(a[i].x);
int fy=Find(a[i].y);
if(a[i].z==1){
fa[fx]=fy;
}else{
if(fx==fy){
printf("NO\n");
flag=1;
break;
}
}
}
if(!flag) printf("YES\n");
}
return 0;
}
但是我们最后发现
t很大,fa数组根本存不下,但n可以存下呀,fa开了许多用不到的空间。
这是我们可以想到用离散化,fa我们不开数字大小,而是开够有多少数字即可
最后把数字离散化为它排第几就可以了
//读入数据
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
book[++tot]=a[i].x;
book[++tot]=a[i].y;
}
//离散化
sort(book+1,book+1+tot);
int reu=unique(book+1,book+tot+1)-book-1;
//把a数组的数字大小改为数字排名
for(int i=1;i<=n;i++){
a[i].x=lower_bound(book+1,book+1+reu,a[i].x)-book;
a[i].y=lower_bound(book+1,book+1+reu,a[i].y)-book;
}
#include
#define maxn 1000001
using namespace std;
int fa[maxn<<1];
int book[maxn<<1];
struct node{
int x,y,z;
}a[maxn];
bool cmp(node a,node b){
return a.z>b.z;
}
int Find(int x){
return x==fa[x] ? x : fa[x]=Find(fa[x]);
}
int main(){
int n,T,tot;
scanf("%d",&T);
while(T--){
scanf("%d",&n);
//初始化
for(int i=1;i<=(n<<1);i++) fa[i]=i;
memset(a,0,sizeof(a));
memset(book,0,sizeof(book));
tot=0;
//读入数据
for(int i=1;i<=n;i++){
scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
book[++tot]=a[i].x;
book[++tot]=a[i].y;
}
//离散化
sort(book+1,book+1+tot);
int reu=unique(book+1,book+tot+1)-book-1;
//把a数组的数字大小改为数字排名
for(int i=1;i<=n;i++){
a[i].x=lower_bound(book+1,book+1+reu,a[i].x)-book;
a[i].y=lower_bound(book+1,book+1+reu,a[i].y)-book;
}
//并查集
sort(a+1,a+1+n,cmp);
bool flag=0;
for(int i=1;i<=n;i++){
int fx=Find(a[i].x);
int fy=Find(a[i].y);
if(a[i].z==1){
fa[fx]=fy;
}else{
if(fx==fy){
printf("NO\n");
flag=1;
break;
}
}
}
if(!flag) printf("YES\n");
}
return 0;
}
在离散化后fa和book数组要开n的二倍哦!
因为有x和y两个数据!数量规模都扩大了二倍
因为数组下标从1开始,函数调用要注意,该加1要加1,该减1要减1!