今天做了一些欧拉函数和并查集得题目,总感觉这两天很没有状态啊,效率非常低下,希望早点恢复吧~~毕竟选拔赛马上就要到了
因为状态原因,没有耐下心来去啃一道难题,也没有去学习新的知识点,复习了一下并查集
我一开使嘛,用很常规的思路去做,每一个组得老大为最后一个给出的人,然后我尝试再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 ",ret); printf("%d ",s[ed]); } return 0; }
——————————————————————————————————————————————————
明天会更好!加油!!