CodeForces 51 E.Pentagon(组合数学)

来源:互联网 发布:取英文名字的软件 编辑:程序博客网 时间:2024/06/06 15:50

Description

给出一个n个点m条边的无向图,问五元环个数

Input

第一行两整数n,m分别表示点数和边数,之后m行每行两个整数u,v表示u,v之间有一条无向边

(1n700,0mn(n1)2)

Output

输出五元环个数

Sample Input

5 5
1 2
2 3
3 4
4 5
5 1

Sample Output

1

Solution

假设一个五元环为uabvcu,可以看出该五元环是由uv的一条长度为2的路径和一条长度为3的路径组成,但是其中有一些不合法的,通过分析u,v,a,b,c中两两相同的情况可以看出,不合法的情况就是一个三元环从某个顶点出去一条边又回来,所以现在问题变成求任意两点之间长度为23的路径数量以及求三元环配一条边的数量,第一个问题只需求出邻接矩阵A的平方B=A2和三次方C=A3,那么B[i][j]C[i][j]就是ij的长度为 23的路径数量,对于三元环,直接枚举i,j,k,两两相连则构成一个三元环,配一条边的时候要注意,比如在i点上多配一条边,由于五元环相邻两点不相同,故在i上可以配deg[i]1条边,进而一个三元环对非法五元环的贡献就是deg[i]+deg[j]+deg[k]3

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;}
阅读全文
0 0
原创粉丝点击