今天做了一些欧拉函数和并查集得题目,总感觉这两天很没有状态啊,效率非常低下,希望早点恢复吧~~毕竟选拔赛马上就要到了
因为状态原因,没有耐下心来去啃一道难题,也没有去学习新的知识点,复习了一下并查集
我一开使嘛,用很常规的思路去做,每一个组得老大为最后一个给出的人,然后我尝试再find函数进行时,减少结点得长度(分级)就是让这条线上的都直接连在老大后面,左后判断每一个结点是不是0得老大,TLE!!!
想了又想,空间换时间,加了一个vis数组,没有出现的都直接过,500ms,一看别人提交的0ms,emmmm,时间差的不是一点半点,0ms一般是再基础得输入数据时进行处理,最后可以直接输出答案,很好,空间换时间,我定义一个sum数组,存储root对应得字节点数量,初始化均为1,放到join数组里面,没实现一个老大合并,就根性sum数组,最后100+ms,凑合吧~~,不再管了,去学学python去吧,换换脑子
include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn = 3e4 + 3e3;
int pre[maxn];
int vis[maxn];
int s[maxn];
void init(int n)
{
for(int i = 0;i <= maxn;i++)
{
pre[i] = i;
s[i] = 1;
}
memset(vis,0,sizeof(vis));
}
int Find(int x)
{
return x == pre[x] ? x : x = Find(pre[x]);
}
void join(int a,int b)
{
int u = Find(a);
int v = Find(b);
if(u != v)
{
pre[u] = v;
s[v] += s[u];
}
}
int main()
{
int n,m,num,a,b;
while(~scanf("%d%d",&n,&m))
{
if(n == 0 && m == 0)break;
init(n);
int ret = 0;
vis[0] = 1;
while(m--)
{
scanf("%d",&num);
num--;
scanf("%d",&a);
vis[a] = 1;
while(num--)
{
scanf("%d",&b);
vis[b] = 1;
join(a,b);
a = b;
}
}
int ed = Find(0);
// for(int i = 0;i < n;i++)
// {
// if(!vis[i])continue;
// if(i == pre[i] && pre[i] == ed)
// {
// ret++;
// }
// else if(Find(i) == ed)
// {
// ret++;
// }
// }
// printf("%d\n",ret);
printf("%d\n",s[ed]);
}
return 0;
}
——————————————————————————————————————————————————
明天会更好!加油!!