当前位置:   article > 正文

hdu 3184 三元环计数_uu3184

uu3184

Counting Stars

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1622    Accepted Submission(s): 444


Problem Description
Little A is an astronomy lover, and he has found that the sky was so beautiful!

So he is counting stars now!

There are n stars in the sky, and little A has connected them by m non-directional edges.

It is guranteed that no edges connect one star with itself, and every two edges connect different pairs of stars.

Now little A wants to know that how many different "A-Structure"s are there in the sky, can you help him?

An "A-structure" can be seen as a non-directional subgraph G, with a set of four nodes V and a set of five edges E.

If   and  , we call G as an "A-structure".

It is defined that "A-structure"   and   are same only in the condition that   and  .
 

Input
There are no more than 300 test cases.

For each test case, there are 2 positive integers n and m in the first line.



And then m lines follow, in each line there are two positive integers u and v, describing that this edge connects node u and node v.



,
 

Output
For each test case, just output one integer--the number of different "A-structure"s in one line.
 

Sample Input
 
 
4 51 22 33 44 11 34 61 22 33 44 11 32 4
 

Sample Output
 
 
16

思路: 我们发现每一个星结构其实就是共享一条边的两个三元环,所以我们要做的就是对每一条边进行计数看其能组成几个不同的三元环。 然后C(x,2)就是答案

代码1:(要慢一点 )

  1. //方法一: m * sqrt(m)
  2. #include<bits/stdc++.h>
  3. using namespace std;
  4. typedef long long ll;
  5. const int N =1e5+5;
  6. const ll lim=1e5+5;
  7. int deg[N];
  8. set<ll >se;
  9. vector< int >ve[N];
  10. int vis[N];
  11. int n,m;
  12. int _hs[N];
  13. void init()
  14. {
  15. memset(vis,0,sizeof(vis));
  16. memset(deg,0,sizeof(deg));
  17. se.clear();
  18. memset(_hs,0,sizeof(_hs));
  19. for(int i=0;i<N;i++) ve[i].clear();
  20. return ;
  21. }
  22. void solve()
  23. {
  24. int up=sqrt(1.0*m);
  25. ll ans=0;
  26. for(int a=1;a<=n;a++)
  27. {
  28. vis[a]=1;
  29. for(int i=0;i<ve[a].size();i++) _hs[ve[a][i]]=a;
  30. for(int i=0;i<ve[a].size();i++){
  31. int b=ve[a][i];
  32. if(vis[b]) continue;
  33. ll cnt=0;
  34. if(deg[b]<=up)
  35. {
  36. for(int j=0;j<ve[b].size();j++){
  37. int c=ve[b][j];
  38. if(_hs[c]==a) cnt++;
  39. }
  40. }
  41. else{
  42. for(int j=0;j<ve[a].size();j++){
  43. int c=ve[a][j];
  44. if(se.find(ll(b*lim+c))!=se.end()) cnt++;
  45. }
  46. }
  47. ans=ans+cnt*(cnt-1)/2;
  48. }
  49. }
  50. printf("%lld\n",ans);
  51. }
  52. int main()
  53. {
  54. while(scanf("%d %d",&n,&m)!=EOF)
  55. {
  56. init();
  57. int u,v;
  58. for(int i=1;i<=m;i++)
  59. {
  60. scanf("%d %d",&u,&v);
  61. deg[u]++;
  62. deg[v]++;
  63. se.insert(ll(u*lim+v));
  64. se.insert(ll(v*lim+u));
  65. ve[u].push_back(v);
  66. ve[v].push_back(u);
  67. }
  68. solve();
  69. }
  70. return 0;
  71. }

代码2 :(定义图的方向,建成有向无环图 遍历的时候更快一些)

  1. //单向建图 建图完毕后为有向无环图
  2. #include<bits/stdc++.h>
  3. #define LL long long
  4. using namespace std;
  5. typedef pair<int ,int > pii;
  6. typedef long long ll;
  7. const int N =1e5+5;
  8. const int M =2e5+5;
  9. const ll lim=1e5+5;
  10. ll cnt[M];
  11. int deg[N];
  12. int x[M];
  13. int y[M];
  14. vector<pii>ve[N];
  15. int n,m;
  16. int pos[N];
  17. int jud[N];
  18. void solve()
  19. {
  20. //ll tot=0; 三元环个数
  21. for(int i=1;i<=m;i++)
  22. {
  23. int u=x[i]; int v=y[i];
  24. for(int j=0;j<ve[u].size();j++){
  25. int uu=ve[u][j].first;
  26. int inde=ve[u][j].second;
  27. pos[uu]=inde;
  28. jud[uu]=i+1;
  29. }
  30. for(int j=0;j<ve[v].size();j++)
  31. {
  32. int vv=ve[v][j].first;
  33. if(jud[vv]==i+1){
  34. //tot++;
  35. cnt[i]++; // 三元环对应的三条边分别 ++
  36. cnt[pos[vv]]++;
  37. cnt[ve[v][j].second]++;
  38. }
  39. }
  40. }
  41. //cout<<tot<<endl;
  42. ll ans=0;
  43. for(int i=1;i<=m;i++){
  44. ans=ans+cnt[i]*(cnt[i]-1)/2;
  45. }
  46. printf("%lld\n",ans);
  47. }
  48. void init()
  49. {
  50. for(int i=0;i<=n;i++){
  51. deg[i]=pos[i]=jud[i]=0;
  52. ve[i].clear();
  53. }
  54. }
  55. int main()
  56. {
  57. while(scanf("%d %d",&n,&m)!=EOF)
  58. {
  59. init();
  60. int u,v;
  61. for(int i=1;i<=m;i++){
  62. scanf("%d %d",&u,&v);
  63. deg[u]++; deg[v]++;
  64. x[i]=u; y[i]=v;
  65. }
  66. for(int i=1;i<=m;i++){
  67. cnt[i]=0;
  68. if(deg[x[i]]<deg[y[i]]){
  69. ve[x[i]].push_back(pii(y[i],i));
  70. }
  71. else if(deg[x[i]]>deg[y[i]]){
  72. ve[y[i]].push_back(pii(x[i],i));
  73. }
  74. else{
  75. if(x[i]<=y[i]){
  76. ve[x[i]].push_back(pii(y[i],i));
  77. }
  78. else ve[y[i]].push_back(pii(x[i],i));
  79. }
  80. }
  81. /*
  82. for(int i=1;i<=n;i++) cout<<ve[i].size()<<" ";
  83. cout<<endl;
  84. */
  85. solve();
  86. }
  87. return 0;
  88. }


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/64647?site
推荐阅读
相关标签
  

闽ICP备14008679号