$义乌普及组2018预赛 聚会$

前置芝士:并查集

说到义乌普及组2018预赛
我就想起... 那是真的OI两开花。(雾

(problem↓)

小白有n个同学,他要开p次聚会,每次他会邀请两个同学参加聚会。并且他知道这n个同学之间的朋友关系,如果a和b是朋友,b和c是朋友,则a和c也是朋友。
给出m对朋友关系,p次聚会,请判断每次被邀请的两个人是否为朋友关系。

Input Data
第一行3个整数n,m,p。分别表示n个同学,m对朋友关系,p次聚会。
接下来n行,每行一个字符串,依次表示每个同学的名字。(字符串长度≤11,且全部位大写字母)
接下来m行,每行两个字符串,用空格隔开,表示为朋友关系的两个人的名字;
接下来p行,每行两个字符串,依次表示每次聚会被邀请的两个人的名字。

Output Data
输出p行,每行一个整数1或者0,其中1表示朋友关系,0表示非朋友关系。

 Input / Output Sample
3 1 1
AAA
BBB
CCC
AAA CCC
AAA BBB
0

对于30%的数据1≤n,m,p≤100;
对于50%的数据1≤n,m,p≤1000;
对于100%的数据1≤n,m,p≤2000;

一年前刚学OI 只会用数组。 而一年后 回过来做这题。 觉得特简单(优越感油然而生)
emmm 废话不多。 这题就是个板子。(而且还是个并查集板子)
重要的是怎么储存这个编号 然后并查集。
不难想。我们可以用(MAP)吖。
这样就很简单了。

//并查集板子
inline int find(int x) {
	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]) ;
}

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

完整代码

#ifdef Dubug

#endif
#include <bits/stdc++.h>
using namespace std;
typedef long long LL ;
inline LL In() { LL res(0),f(1); register char c ;
	while(isspace(c=getchar())) ; c == '-'? f = -1 , c = getchar() : 0 ;
	while(res = (res << 1) + (res << 3) + (c & 15) , isdigit(c=getchar())) ;
	return res * f ;
}

map <string , int> mp ;
const int N = 2000 + 5 ;
int n , m , p ;
int fa[N] ;

inline int find(int x) {
	return fa[x] == x ? fa[x] : fa[x] = find(fa[x]) ;
}

inline void merge(int x,int y) {
	fa[find(x)] = find(y) ;
}
signed main () {
	ios::sync_with_stdio(false) ;
	cin >> n >> m >> p ;//n = In() , m = In() , p = In() ;
	for(register int i=1;i<=N;i++) fa[i] = i ;
	for(register int i=1;i<=n;i++) {
		string s ; cin >> s ;
		mp[s] = i ;
	}
	for(register int i=1;i<=m;i++) {
		string s1 , s2 ; cin >> s1 >> s2 ;
		merge(mp[s1],mp[s2]) ;
	}
	for(register int i=1;i<=p;i++) {
		string s1 , s2 ; cin >> s1 >> s2 ;
		puts(find(mp[s1]) == find(mp[s2])?"1":"0") ;
	}
	return 0 ;
}
不存在十全十美的文章 如同不存在彻头彻尾的绝望
原文地址:https://www.cnblogs.com/qf-breeze/p/10591128.html