题解 LuoguP2256 【一中校运会之百米跑】

并查集 \(+\) \(STL\) \(map+struct\)做法

本来我是不想写\(map\)的,但是害怕像下面这样子写会超时(后来才知道其实不会超时)

struct node
{
    int rank;
    string name;
}father[20010];
int strfind(string a)
{
    for(int i=1;i<=n;i++)
        if(father[i].name==a)return i;
}

那就写个\(map\)吧,跑起来还挺快的,没吸氧\(18ms\)

主要思想:将选手编号为\(1\)~\(n\),将选手编号存入\(map\)当中,这样就可以根据名字快速的找到选手的编号,然后定义一个\(struct\),并查集部分根据结构体稍微修改就OK了。

AC代码如下(有注释):

#pragma GCC diagnostic error "-std=c++11"
#include <iostream>
#include <cstdio>
#include <map>
using namespace std;
template<class T>void r(T &a)//快读
{
    T s=0,w=1;a=0;char ch=getc(stdin);
    while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getc(stdin);}
    while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getc(stdin);}
    a=w*s;
}
template<class T,class... Y>void r(T& t,Y&... a){r(t);r(a...);}//不定参数的快读
struct node
{
    int rk;//选手编号
    string na;
};
struct bcj//将并查集封装在一个结构体里
{
    node father[20010];//并查集的father数组
    int find(int x)//并查集的“查”操作
{if(father[x].rk!=x)father[x].rk=find(father[x].rk);return father[x].rk;}
    void unionn(int x,int y)//并查集的“并”操作
    {x=find(x);y=find(y);if(x!=y)father[y].rk=x;}
    bool judge(int x,int y)//判断两个人是否处于一个组
    {if(find(x)==find(y))return true;return false;}
};
map<string,int>ma;//定义一个以string为下标的int型数组,用于快速寻找选手编号
int main()
{
    int n,m;
    r(n,m);
    bcj ufs;//定义一个并查集
    for(int i=1;i<=n;i++)
    {
        ufs.father[i].rk=i;//存入选手编号
        string a;
        cin>>a;
        ufs.father[i].na=a;//存入人名
        ma[a]=i;//将选手编号以及人名存入map
    }
    for(int i=1;i<=m;i++)
    {
        string a,b;
        cin>>a>>b;
        ufs.unionn(ma[a],ma[b]);//寻找选手编号,并进行并查集的“并”操作
    }
    int q;
    r(q);
    for(int i=1;i<=q;i++)
    {
        string a,b;
        cin>>a>>b;
        printf(ufs.judge(ma[a],ma[b])?"Yes.\n":"No.\n");//判断两人是否在一个组里,是,输出"Yes.",不是,输出"No."
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/Naive-Cat/p/10664249.html