$义乌普及组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 
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  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

你可能感兴趣的:($义乌普及组2018预赛 聚会$)