原题题目
题面经过我校选手感性+理性+恶搞翻译。
众所周知,在北京理工大学有两位ACM英雄分别被称为 foreverlasting \text{foreverlasting} foreverlasting 和 fried-chicken \text{fried-chicken} fried-chicken。
他们分别沉浸在完美的爱情中。以下链接讲述了 fried-chicken \text{fried-chicken} fried-chicken 的爱情故事。
DuangDuck \text {DuangDuck} DuangDuck 喜欢图论和数学,他需要你的帮助解决一个简单的问题。
给定一个简单无向图命名为 fried-chicken \text{fried-chicken} fried-chicken,其中有 n n n 个节点和 m m m 条边。请注意,该图不一定是连通的。节点从 1 1 1 到 n n n 进行标号。
DuangDuck \text {DuangDuck} DuangDuck 想知道在 fried-chicken \text{fried-chicken} fried-chicken 图中有多少个 foreverlasting \text{foreverlasting} foreverlasting 图。
以上图像定义了一个 foreverlasting \text{foreverlasting} foreverlasting 图。
请注意,当两个 foreverlasting \text{foreverlasting} foreverlasting 图的边集之间至少有一条不同的边时,这两个图被认为是不同的。
换句话说,给定的图 G ( V , E ) G(V,E) G(V,E)。你需要计算满足 V ′ = { v 1 , v 2 , v 3 , v 4 , v 5 , v 6 , v 7 , v 8 } , E ′ = { ( v 1 , v 3 ) , ( v 2 , v 3 ) , ( v 3 , v 4 ) , ( v 3 , v 5 ) , ( v 3 , v 6 ) , ( v 3 , v 7 ) , ( v 4 , v 8 ) , ( v 5 , v 8 ) , ( v 6 , v 8 ) , ( v 7 , v 8 ) } V′=\{v_1,v_2,v_3,v_4,v_5,v_6,v_7,v_8\},E′=\{(v_1,v_3),(v_2,v_3),(v_3,v_4),(v_3,v_5),(v_3,v_6),(v_3,v_7),(v_4,v_8),(v_5,v_8),(v_6,v_8),(v_7,v_8)\} V′={v1,v2,v3,v4,v5,v6,v7,v8},E′={(v1,v3),(v2,v3),(v3,v4),(v3,v5),(v3,v6),(v3,v7),(v4,v8),(v5,v8),(v6,v8),(v7,v8)} 的子图 G ′ ( V ′ , E ′ ) G′(V′,E′) G′(V′,E′) 的数量。
由于答案可能非常大, DuangDuck \text {DuangDuck} DuangDuck 想知道答案对 1 0 9 + 7 10^9+7 109+7 取模的结果。
样例
输入样例
1
8 10
1 2
1 3
1 4
1 5
1 6
1 7
8 4
8 5
8 6
8 7
输出样例
1
题目解析
考虑暴力枚举,显然会时超,可以考虑枚举比较关键的点。
我们发现中间四个点链接的两个点比较好枚举,我们枚举这两个点,为 ( i , j ) (i,j) (i,j),在两者都连接的点 x x x 的集合 X X X 中选择四个作为中间点,方案为 C size X 4 C_{\text {size}_X}^4 CsizeX4。
同理我们再在 i i i 连接的点 y y y 的集合 Y Y Y 中选择两个作为上面的点,方案为 C size Y − 4 2 C_{\text {size}_Y-4}^2 CsizeY−42。
显然这里的减四是因为前面已经从 Y Y Y 的子集 X X X 中选择了四个点。
注意特判 j ∈ Y j\in Y j∈Y 的情况,此时 Y Y Y 集合不可以选择 j j j,否则形状是不对的,因此需要减 5 5 5。
两者相乘即可。
时间复杂度为 O ( n 3 64 ) O(\dfrac{n^3}{64}) O(64n3),足够通过本题。
注意需要适当卡常,以下代码常数可能比较大。
代码实现
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const LL N=1005;
const LL mod=1e9+7;
LL T,n,m,x,y;
bitset<N>a[N];
LL C(LL x,LL y)
{
if(x<y)return 0;
if(y==2)return (x*(x-1)/2)%mod;
return (x*(x-1)*(x-2)*(x-3)/24)%mod;
}
int main()
{
scanf("%lld",&T);
while(T--)
{
for(int i=1;i<=n;i++)a[i]=a[0];
scanf("%lld%lld",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%lld%lld",&x,&y);
a[x][y]=1,a[y][x]=1;
}
LL ans=0;
for(int i=1;i<=n;i++)
{
LL k=a[i].count();
for(int j=1;j<=n;j++)
{
if(i==j)continue;
bitset<N>tmp=a[i]&a[j];
if(a[i][j]==1)ans+=C(tmp.count(),4)*C(k-5,2)%mod;
else ans+=C(tmp.count(),4)*C(k-4,2)%mod;
ans%=mod;
}
}
printf("%lld\n",ans);
}
}