题解 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;
}
标签:校运会,查集,int,题解,LuoguP2256,father,选手,find,rk 来源: https://www.cnblogs.com/Naive-Cat/p/10664249.html