1. 程式人生 > 實用技巧 >P1955 [NOI2015]程式自動分析

P1955 [NOI2015]程式自動分析

題意

略(這東西應該都能看懂)

思路

先排序,把所有e=1的操作放在前面,然後再進行e=0的操作在進行e=1的操作的時候,我們只要把它約束的兩個變數放在同一個集合裡面即可。再e=0,即存在一條不相等的約束條件,對於它約束的兩個變數,如果在一個集合裡面,那就不可能滿足!如不相等的約束條件都滿足,那就YES。

顯然並查集,但是因為資料範圍到了 \(1e9\) 所以我們需要使用離散化(不開也行,也就是會MLE)

程式碼

#include<cstdio>
#include<iostream>
#include<algorithm> 
#include<cstring>
#include<string>
#include<cmath>
#include<cstdlib>
#define int long long

using namespace std;

int t,n,f[1000007],book[1000007*3];

struct node{
	int x,y,e;
}a[1000001];
bool cmp(node a,node b){
	return a.e>b.e;
}

int find(int x){
	if(x==f[x]) return x;
	return f[x]=find(f[x]);
}

signed main(){
	scanf("%lld",&t);
	while(t--){
		int tot=-1;
		memset(book,0,sizeof(book));
		memset(a,0,sizeof(a));
		memset(f,0,sizeof(f));
		int flag=1;
		scanf("%lld",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].e);
			book[++tot]=a[i].x;
			book[++tot]=a[i].y;
		}
		sort(book,book+tot);//排序
		int reu=unique(book,book+tot)-book;//去重
		for(int i=1;i<=n;++i){
			a[i].x=lower_bound(book,book+reu,a[i].x)-book;
			a[i].y=lower_bound(book,book+reu,a[i].y)-book;
		}
		for(int i=1;i<=reu;i++) f[i]=i;//初始化
		sort(a+1,a+n+1,cmp);//按e排序
		for(int i=1;i<=n;i++){
			int r1=find(a[i].x);
			int r2=find(a[i].y);
			if(a[i].e){
				f[r1]=r2;
			}else if(r1==r2){
				printf("NO\n");
				flag=0;
				break;
			}
		}
		if(flag) printf("YES\n");
	}
	return 0;
}

\[注意初始化 f[i]=i \\ 沒了 \]