Description
给出一个
n
个点
Input
第一行两整数
n,m
分别表示点数和边数,之后
m
行每行两个整数
(1≤n≤700,0≤m≤n(n−1)2)
Output
输出五元环个数
Sample Input
5 5
1 2
2 3
3 4
4 5
5 1
Sample Output
1
Solution
假设一个五元环为
u→a→b→v→c→u
,可以看出该五元环是由
u→v
的一条长度为
2
的路径和一条长度为
Code
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=705;
ll A[maxn][maxn],B[maxn][maxn],C[maxn][maxn];
int n,m,deg[maxn];
void Mul(ll A[][maxn],ll B[][maxn],ll C[][maxn])
{
for(int i=1;i<=n;i++)
for(int j=1;j<=i;j++)
{
C[i][j]=0;
for(int k=1;k<=n;k++)C[i][j]+=A[i][k]*B[k][j];
C[j][i]=C[i][j];
}
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
for(int i=1;i<=n;i++)
{
deg[i]=0;
for(int j=1;j<=n;j++)A[i][j]=0;
}
while(m--)
{
int u,v;
scanf("%d%d",&u,&v);
A[u][v]=A[v][u]=1;
deg[u]++,deg[v]++;
}
Mul(A,A,B);
Mul(A,B,C);
ll ans=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
ans+=B[i][j]*C[i][j];
ans/=10;
for(int i=1;i<=n;i++)
for(int j=i+1;j<=n;j++)
if(A[i][j])
for(int k=j+1;k<=n;k++)
if(A[i][k]&&A[j][k])
ans-=(deg[i]+deg[j]+deg[k]-3);
printf("%I64d\n",ans);
}
return 0;
}