jzoj 1499. 街道 (Standard IO)

Description
在城市裏很容易迷路,有的街道一會兒平行一會兒又相交。現在市長爲了維護城市形象,他表示:“我們的街道要麼平行,要麼垂直相交,不存在其他關係”。
你作爲觀察員準備去當地實地考察,得到一些街道之間的關係,這些關係只能是平行和垂直相交兩種。
輸入這些街道的關係,同時提出一些新的問題,你來幫忙回答。

Input
輸入第一行包含兩個整數M和N(1<=M,N<=100000),接下來M行每行包含一個考察結果,每個考察結果包含三個用若干個空格隔開的單詞組成:兩個街道的名字和“parallel”或“intersect”表示這兩條街道之間的關係,每個街道的名字由不超過100個大寫或小寫字母組成。
接下來N行描述N次詢問,每行輸入兩個由若干個空格隔開的街道名。

Output
如果考察結果與市長的話有矛盾,則輸出“Waterloo”,否則輸出N行,第i行對應第i次詢問的結果,有“parallel”、“intersect”和“unknown”三種情況,分別表示“平行”、“垂直相交”以及“不知道”

Sample Input
3 3
fourthstreet fifthstreet parallel
fifthstreet sixthstreet parallel
fourthavenue fifthstreet intersect
sixthstreet fourthstreet
sixthstreet fourthavenue
sixthstreet King

Sample Output
parallel
intersect
unknown

Data Constraint

Hint
Sample Input2:
2 1
King Weber parallel
King Weber intersect
King Weber

Sample Output2:
Waterloo

【數據說明】
20%的數據 1<=M,N<=100;
100%的數據 1<=M,N<=100000

題目大意:

給你 nn 條關於街道的關係(平行或垂直),求問任意兩條街道的關係。

題解:

種類並查集, xx 表與 xx 平行的集合, x+Nx+Nx⊥x 的集合,
在讀入時一邊更新關係,一邊判斷是否合法,
若關係爲 xxyy 平行,則合併平行 xyx,y 的集合,合併 xy⊥x,⊥y 的集合,
若關係爲 xxyy 垂直,則合併平行 xyx,⊥y 的集合,合併 xy⊥x,y 的集合,
xxx⊥x 的平行,則不合法,

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
#include<map>
#define N 400005
using namespace std;

int i,m,t,num;
int fa[2*N];
char c;
string a,b,re;

map<string,int> hash;

string reads() {
	c=getchar(),re="";
	while ((c>='a'&&c<='z')||(c>='A'&&c<='Z')) {
		re+=c; c=getchar();
	}
	return re;
}

int get(int x) {
	if (fa[x]==x) return x;
	return fa[x]=get(fa[x]);
}

void merge(int x,int y) {
	fa[get(x)]=get(y);
}

int main()
{
	scanf("%d %d\n",&m,&t);
	for (i=1;i<=m;i++) {
		a=reads();
		if (!hash[a]) hash[a]=++num,fa[num]=num,fa[num+N]=num+N;
		b=reads();
		if (!hash[b]) hash[b]=++num,fa[num]=num,fa[num+N]=num+N;		
		if (reads()=="parallel") {
			merge(hash[a],hash[b]);
			merge(hash[a]+N,hash[b]+N);
		} else {
			merge(hash[a]+N,hash[b]);
			merge(hash[a],hash[b]+N);
		}
		if (get(hash[a])==get(hash[b])&&get(hash[a])==get(hash[b]+N)) {
			printf("Waterloo"); return 0;
		}
	}
	for (i=1;i<=t;i++) {
		a=reads(); b=reads();
		if (get(hash[a])==get(hash[b])||get(hash[a]+N)==get(hash[b]+N)) printf("parallel\n"); else
		if (get(hash[a]+N)==get(hash[b])||get(hash[a])==get(hash[b]+N)) printf("intersect\n"); else
		printf("unknown\n");
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章