vijos 1697平面几何

AC通道: https://vijos.org/p/1697

[分析]

看到这道题目,我最先想到的是Bzoj1370,明显的并查集呀

我们设直线A‘为与直线A垂直的直线,而互相平行的直线可以互相合并。

若直线A垂直于直线B,则直线A平行于直线B',这样就可以把垂直转换为平行。

具体实现过程请参考代码。

#include <iostream>
#include <cstdio>
#include <cstring>

using namespace std;

int n,m,q;
int fa[2000];

int find(int x){
	int tmp=x,pre;
	while(tmp!=fa[tmp])tmp=fa[tmp];
	while(x!=tmp){
		pre=fa[x];
		fa[x]=tmp;
		x=pre;
	}
	return tmp;
}

void merge(int x,int y){
	int fx=find(x),fy=find(y);
	fa[fx]=fy;
}

int main(){
	scanf("%d%d%d",&n,&m,&q);
	for(int i=1;i<=2*n;i++)fa[i]=i;
	for(int i=1;i<=m;i++){
		char c[100],ch;int a,b;
		scanf("%s",c);
		a=c[1]-'0';
		if(c[2]>='0'&&c[2]<='9')a=a*10+c[2]-'0';
		if(c[3]>='0'&&c[3]<='9')a=a*10+c[3]-'0';
		scanf("%s",c);
		ch=c[0];
		scanf("%s",c);
		b=c[1]-'0';
		if(c[2]>='0'&&c[2]<='9')b=b*10+c[2]-'0';
		if(c[3]>='0'&&c[3]<='9')b=b*10+c[3]-'0';
		if(ch=='p'){
			if(find(a)==find(b+n)){
				printf("There must be something wrong...\n");
				return 0;
			}
			merge(a,b);
            merge(a+n,b+n);
		}
		else{
			if(find(a)==find(b)){
				printf("There must be something wrong...\n");
				return 0;
			}
			merge(a+n,b);
			merge(a,b+n);
		}
	}
	int nums=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			if((find(i)==find(j)||find(i+n)==find(j+n))&&(i!=j))
				nums++; 
	printf("%d\n",nums/2);
	for(int i=1;i<=q;i++){
		int a,b;
		char c[100];
		scanf("%s",c);
		a=c[1]-'0';
		if(c[2]>='0'&&c[2]<='9')a=a*10+c[2]-'0';
		if(c[3]>='0'&&c[3]<='9')a=a*10+c[3]-'0';
		scanf("%s",c);
		b=c[1]-'0'; 
		if(c[2]>='0'&&c[2]<='9')b=b*10+c[2]-'0';
		if(c[3]>='0'&&c[3]<='9')b=b*10+c[3]-'0';
		if(find(a)==find(b)||find(a+n)==find(b+n)){
			printf("Parallel.\n");
		}
		else if(find(a+n)==find(b)||find(b)==find(a+n))printf("Vertical.\n");
		else printf("No idea.\n");
	}
	return 0;
}





你可能感兴趣的:(编程)