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.
2≤n≤105, 1≤m≤min(2×105,n(n−1)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.
1≤u,v≤n
∑n≤3×105,∑m≤6×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#include#include#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]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; }