Evanyou Blog 彩带

HDU 6184 Counting Stars

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 V=(A,B,C,D)and E=(AB,BC,CD,DA,AC), we call G as an "A-structure".
It is defined that "A-structure" G1=V1+E1 and G2=V2+E2 are same only in the condition that V1=V2 and E1=E2
 
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.
2n1051mmin(2×105,n(n1)2)
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.
1u,v
n3×105,m6×105
 
Output
For each test case, just output one integer--the number of different "A-structure"s in one line.
 
Sample Input
4 5
1 2
2 3
3 4
4 1
1 3
4 6
1 2
2 3
3 4
4 1
1 3
2 4
 
Sample Output
1
6

 

题意:给定一张无向图,求有公共边的三元环对数。

 

Solution:

  三元环裸题。

  直接三元环计数,然后开一个桶记录一下每条边在多少个三元环中出现,最后的答案就是$\sum_\limits{i=1}^{i\leq m}{\frac{tot[i]*(tot[i]-1)}{2}}$。

代码:

/*Code by 520 -- 9.10*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define il inline
#define ll long long
#define RE register
#define For(i,a,b) for(RE int (i)=(a);(i)<=(b);(i)++)
#define Bor(i,a,b) for(RE int (i)=(b);(i)>=(a);(i)--)
using namespace std;
const int N=100005,M=200005;
int n,m,to[M],net[M],h[N],cnt,tot[M],pre[N],vis[N],deg[N];
struct node{
    int u,v;    
}e[M];
ll ans;

il void add(int u,int v){to[++cnt]=v,net[cnt]=h[u],h[u]=cnt;}

int main(){
    while(scanf("%d%d",&n,&m)==2){
        For(i,1,m) scanf("%d%d",&e[i].u,&e[i].v),deg[e[i].u]++,deg[e[i].v]++;
        For(i,1,m) {
            RE int u=e[i].u,v=e[i].v;
            if(deg[u]<deg[v]||deg[u]==deg[v]&&u>v) swap(u,v);
            add(u,v);
        }
        For(u,1,n){
            for(RE int i=h[u];i;i=net[i]) vis[to[i]]=u,pre[to[i]]=i;
            for(RE int i=h[u];i;i=net[i]){
                RE int v=to[i];
                for(RE int j=h[v];j;j=net[j]){
                    RE int w=to[j];
                    if(vis[w]==u) ++tot[i],++tot[j],++tot[pre[w]];
                }
            }
        }
        For(i,1,cnt) ans+=1ll*tot[i]*(tot[i]-1)/2;
        printf("%lld\n",ans);
        memset(h,0,sizeof(h)),memset(deg,0,sizeof(deg)),
        memset(tot,0,sizeof(tot)),memset(pre,0,sizeof(pre)),
        memset(vis,0,sizeof(vis)),cnt=0,ans=0;
    }
    return 0;    
}

 

posted @ 2018-09-10 22:31  five20  阅读(232)  评论(0编辑  收藏  举报
Live2D