当前位置:   article > 正文

CF#318-B - Bear and Three Musketeers-暴力寻找三元环_如何找三元环

如何找三元环

题意是给你n个点m条边

求出一个三元环(与a相连的边包括b,c)、(与b相连的边包括a,c)(与c相连的边包括a,b)

n,m都是1-4000

一开始觉得暴力枚举复杂度肯定过不了。

随手打了一发交了一次居然才62ms......后来再算算 的确数据规模有点小,直接暴力就可以了


因为需要这个操作 与b相连的所有边中寻找是否存在c,所以直接用set构建邻接表了,查找就可以logn了


暴力枚举每一条度数大于2的边,对所有与它相连的边,查询(b中是否有c,c中是否有b)、如果为真,则abc为三元环

然后一直更新 a.size+b.size+c.size-6  (减6是因为 recognition 是不包括环内的队友的

复杂度是  o(n)-o(n^2)  

最糟糕的情况是  所有边连接在一个点上  


  1. #include <cstdio>
  2. #include <cmath>
  3. #include <cstring>
  4. #include <string>
  5. #include <algorithm>
  6. #include <iostream>
  7. #include <queue>
  8. #include <map>
  9. #include <set>
  10. #include <vector>
  11. using namespace std;
  12. #define inf 2147483647
  13. set<int> qq[4005];
  14. set<int> ::iterator it,tmp,t1,t2;
  15. int main()
  16. {
  17. int n,i,j,tt,m;
  18. scanf("%d%d",&n,&m);
  19. for(i=1;i<=m;i++)
  20. {
  21. scanf("%d%d",&tt,&j);
  22. qq[tt].insert(j);
  23. qq[j].insert(tt);
  24. }
  25. int maxx=inf;
  26. for (i=1;i<=n;i++)
  27. {
  28. if (qq[i].size()<2) continue;
  29. for (it=qq[i].begin();it!=qq[i].end();it++)
  30. {
  31. tmp=it;
  32. tmp++;
  33. //printf("%d %d--\n",*it,*tmp);
  34. for (;tmp!=qq[i].end();tmp++)
  35. {
  36. if ( qq[(*it)].count(*tmp)&&qq[(*tmp)].count(*it) )
  37. {
  38. int ans=qq[*it].size()+qq[*tmp].size()+qq[i].size();
  39. if (ans-6<maxx)
  40. maxx=ans-6;
  41. }
  42. }
  43. }
  44. }
  45. if (maxx==inf)
  46. printf("-1\n");
  47. else
  48. printf("%d\n",maxx);
  49. return 0;
  50. }


本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号