牛客网多校7 E Counting 4-Cliques

链接:https://www.nowcoder.com/acm/contest/145/E
来源:牛客网

题目描述
You love doing graph theory problems. You’ve recently stumbled upon a classical problem : Count the number of 4-cliques in an undirected graph.

Given an undirected simple graph G, a 4-clique of G is a set of 4 nodes such that all pairs of nodes in this set are directly connected by an edge.

This task would be too easy for you, wouldn’t it? Thus, your task here is to find an undirected simple graph G with exactly k 4-cliques. Can you solve this task?

输入描述:
The first line of input contains a single integer k (1 ≤ k ≤ 106).
输出描述:
On the first line, output two space-separated integers, n, m (1 ≤ n ≤ 75, 1 ≤ m ≤ n * (n - 1) / 2). On the next m lines, output two space-separated integers denoting an edge of the graph u, v (1 ≤ u, v ≤ n), where u and v are the endpoints of the edge.

Your graph must not contain any self-loops or multiple edges between the same pair of nodes. Any graph that has exactly k 4-cliques and satisfies the constraints will be accepted. It can be proven that a solution always exist under the given constraints.
示例1
输入
复制
1
输出
复制
4 6
1 2
1 3
1 4
2 3
2 4
4 3
说明
In the sample, the whole graph is a 4-clique.
第一次从75个点里面取x个点构成完全图,得到的个数为C(x,4),边数为x*(x-1)/2,之后从x个点里面取y个点,与新的一个点构成完全图,得到个数为C(y,3),新添了y条边,就照着这种思路做类似背包dp。比赛的时候想到这种思路,但是按照贪心找不断找最大的组合数,没有用背包的思想,wa 在了62。

#include"bits/stdc++.h"
using namespace std;
typedef long long ll;
int C[105][105],a[105],cnt,ans,sum;
int st[100001],top;
void dfs(int now,int mx){
    if(now==0){
        if(st[1]+top-1<=75){
             sum=st[1]*(st[1]-1)/2;
            for(int i=2;i<=top;i++)
                sum+=st[i];
            int op=st[1];
            printf("%d %d\n",st[1]+top-1,sum);
            for(int i=1;i<=op;i++){
                for(int j=i+1;j<=op;j++){
                    printf("%d %d\n",i,j);
                }
            }
            for(int i=2;i<=top;i++){
                op++;
                for(int j=1;j<=st[i];j++){
                    printf("%d %d\n",op,j);
                }
            }
            exit(0);//退出程序
        }
        return;
    }
    if(st[1]+top-1>75)return;
    if(!mx){
        for(int i=75;i>=4;i--){
            if(C[i][4]<=now){
                st[++top]=i;
                dfs(now-C[i][4],i);
                top--;
            }
        }
    }
    else{
        for(int i=mx;i>=3;i--){
            if(C[i][3]<=now){
                st[++top]=i;
                dfs(now-C[i][3],i);
                top--;
            }
        }
    }
}
int main(){
    for(int i=1;i<=75;i++){
        C[i][0]=1;
    }
    for(int i=1;i<=75;i++){
        for(int j=1;j<=i;j++){
            if(i==j) C[i][j]=1;
            else if(i>j)
                C[i][j]=C[i-1][j]+C[i-1][j-1];
        }
    }
    int k;
    scanf("%d",&k);
    dfs(k,0);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值