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; }