杭电多校(2)1007

 

As we all know, There are two ACM heros known as foreverlasting and fried-chicken in BIT. They are immersed in perfect love respectively. The following link tells the love story of fried-chicken.

有哪些很治愈的童话故事? - 知乎

Pedestrian1 likes graph and mathematics. He needs your help to solve an easy problem. You are given a simple undirected graph named "fried-chicken" with n nodes and m edges. Please note that the graph is not necessarily connected. The nodes are labeled from 11 to n.

Pedestrian1 wants to know how many "foreverlasting" graphs in the "fried-chicken" graph.

figure

The above image defines a "foreverlasting" graph.

Please note that two "foreverlasting" graphs are considered different when there is at least one different edge between the two edge sets that make up the two "foreverlasting" graphs.

In other word, the given graph is G(V,E). You need to calculate the number of subgraphs G′(V′,E′)(V′⊆V,E′⊆E) which satisfy 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​)}

Since the answer may be very large, Pedestrian1 wants to know the answer modulo 1000000007

 

题意大概为给你一个图,找这个图中有多少个题中给你的图 

这个图的特点就是有两个特殊点,一个连接6个,一个连接4个,所以最朴素做法就是枚举两个点, 

看是否有四个一样的,但是问题就是这样会达到(On^4),所以需要优化

这里用bitset,我们这样储存 : bitset<N> g[N],因为是二进制储存,所以枚举两个点,然后g[i]&g[j]

bitset有一个count函数,是查找二进制中有多少个1, 通过这些操作,我们就可以找到i,j这两个点各有多少个1,以及他两共有多少个相同的1

然后通过求组合数方法  C(cnt,4)*C(a-4,2)

就可以求出有多少个这样的图

 

#include <iostream>
#include <cstring>
#include <ctime>
#include <string>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cmath>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <iomanip>
using namespace std;
# define endl '\n'
#define int long long
typedef pair<int,int>PII;
unordered_map<char,int>mp1;
const int N =1005,mod= 1e9 +7;
const int M=1e5+7;
typedef pair<int, int> PII;

int n,m,k;
int fact[N],infact[N];
bitset<N> g[N];
int qmi(int a, int k, int p)  // 求a^k mod p
{
    int res = 1 % p;
    while (k)
    {
        if (k & 1) res = res * a % p;
        a = a * a % p;
        k >>= 1;
    }
    return res;
}
void init(){
    fact[0]=infact[0]=1;
    for(int i=1;i<N;i++){
        fact[i]=fact[i-1]*i%mod;
        infact[i]=infact[i-1]*qmi(i,mod-2,mod)%mod;
    }
}
int C(int a,int b){
    if(b>a) return 0;
    return fact[a] * infact[b] % mod * infact[a - b] % mod;
}
void solve()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) g[i].reset();
    for(int i=1;i<=m;i++){
        int a,b;cin>>a>>b;
        g[a].set(b),g[b].set(a);
    }
    int res=0;
    //for(int i=1;i<=N;i++){
     //   cout<<fact[i]<<" "<<infact[i]<<endl;
    //}
    for(int i=1;i<=n;i++){
        for(int j=i+1;j<=n;j++){
            auto tmp=g[i]&g[j];
            int cnt=tmp.count();
            cout<<"------>"<<cnt<<endl;
            if(tmp.count()>=4)
            {
                int a=g[i].count(),b=g[j].count();
                if(g[i][j]) a--,b--;
                if(a>=6){
                    res+=C(cnt,4)*C(a-4,2);
                    res%=mod;
                }
                if(b>=6){
                    res+=C(cnt,4)*C(b-4,2);
                    res%=mod;
                }
            }
        }
    }
    cout<<res<<"\n";
}
signed main(){
    cin.tie(0);cout.tie(0);ios::sync_with_stdio(0);
    int t=1;
    init();
    cin>>t;
    while(t--) solve();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

q619718

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值