P1955&&ybtoj【图论】1章2题【程序自动分析】

程序自动分析

题目

程序自动分析


解析

刚开始:这不是道扩展域并查集吗
然后就WA
《五颜六色》
后来发现离散化,而且不需要扩展域,只需要先处理相同,再处理不同,然后就又WA了(还带RE的?)
调了一会,闲得发慌加了个按秩合并,成功避免RE(话说这有什么用)
又发现数组开小了,然而并没有什么用
最终,发现自己手打离散化打错了,终于AC
结论:我是蒟蒻

code:

#include<cstdio>
#include<algorithm>
using namespace std;
struct node{
    
    int a,y;}a[2000010];
int f[2000010],tot[2000010],z[1000010],t,n,s=0,T;//WA+1
bool ok;
bool cmp1(node x,node y){
    
    return x.a<y.a;}
bool cmp2(node x,node y){
    
    return x.y<y.y;}
int find(int dep)
{
    
    
	if(f[dep]==dep)return dep;
	return f[dep]=find(f[dep]);
}
void merge(int x,int y)
{
    
    
	if(!(x^y))return;
	if(tot[x]<tot[y])f[x]=y;
	else f[y]=x;
	if(tot[x]==tot[y])tot[x]++;//乱搞按秩合并
}
int main()
{
    
    
	scanf("%d",&T);
	while(T--)
	{
    
    
		scanf("%d",&n);
		n<<=1;
		for(int i=1;i<=n;i++)
		{
    
    
			scanf("%d",&a[i].a);
			a[i].y=i;
			if(!(i&1))scanf("%d",&z[i>>1]);//所以!i&1和!(i&1)是不同的……
		}
		sort(a+1,a+n+1,cmp1);
		t=0;
		for(int i=1;i<=n;i++){
    
    if(a[i].a!=t)t=a[i].a,a[i].a=a[i-1].a+1;else a[i].a=a[i-1].a;}
		//打挂的离散化上没有else一句
		for(int i=1;i<=a[n].a;i++)f[i]=i,tot[i]=1;
		sort(a+1,a+n+1,cmp2);
		n>>=1;
		for(int i=1;i<=n;i++)if(z[i])merge(find(a[(i<<1)-1].a),find(a[i<<1].a));
		for(int i=1;i<=n;i++)if((!z[i])&&(find(a[i<<1].a)==find(a[(i<<1)-1].a))){
    
    ok=1;break;}
		if(!ok)printf("YES\n");
		else printf("NO\n"),ok=0;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/113095208