列表

详情


NC17489. Counting 4-Cliques

描述

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.

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

Python3 解法, 执行用时: 601ms, 内存消耗: 5112K, 提交时间: 2022-07-10 18:41:16

def rec(n,m):
    if m >= n:
        return 1
    elif m == 1:
        return n
    else:
        return rec(n-1,m-1)+rec(n-1,m)
    

c3 = [rec(i, 3) for i in range(0, 72)]
c4 = [rec(i, 4) for i in range(0, 72)]


lst = []
def sz(a):
  if len(a) == 0:
    return 0
  return a[0] + len(a) - 1

d = 1
s = set()

def dfs(x):
  if sz(lst) > 75:
    return 
  if x == 0:
    # s.add(d)
    # raise Exception
    # print(2)

    n = lst[0]
    m = 0
    edge = []
    for i in range(1, n + 1):
      for j in range(i + 1, n + 1):
        edge.append([i, j])
    for k in lst[1:]:
      n += 1
      for i in range(1, k + 1):
        edge.append([i, n])
    m = len(edge)
    print('{} {}'.format(n, m))
    for i, j in edge:
      print('{} {}'.format(i, j))
    exit(0)

  if sz(lst) == 0:
    for i in range(len(c4) - 1, 3, -1):
      if x < c4[i]:
        continue
      lst.append(i)
      dfs(x - c4[i])
      lst.pop()
  else:
    for i in range(lst[-1], 2, -1):
      if x < c3[i]:
        continue
      lst.append(i)
      dfs(x - c3[i])
      lst.pop()


T = int(input())
dfs(T)

C++ 解法, 执行用时: 25ms, 内存消耗: 484K, 提交时间: 2021-10-08 14:59:27

#include<iostream>
#include<algorithm>
#include<cstring>
#define rep(i,a,b) for(int i=a;i<(int)b;i++)
#define mem(a,b) memset(a,b,sizeof(a))
#include<queue>
using namespace std;
typedef int64_t ll;
const int maxn=1e3+9;
int C4[maxn],C3[maxn],k,cpgn;
int deg[9];
void dfs(int v,int d,int num){
	if(d==5||v==0){
		if(v) return;
		typedef pair<int,int> pii;
		vector<pii> ans;
		for(int i=1;i<=cpgn;i++) for(int j=1;j<i;j++)
			ans.push_back({i,j});
		for(int i=0;i<d;i++){
			for(int j=1;j<=deg[i];j++) ans.push_back({71+i,j});
		}
		printf("75 %d\n",(int)ans.size());
		for(auto [u,v]:ans) printf("%d %d\n",u,v);
		exit(0);
	}
	for(int i=1;i<=num;i++){
		if(C3[i]>v) break;
		deg[d]=i;
		dfs(v-C3[i],d+1,i);
	}
}
int main(){
	for(int i=2;i<=80;i++){
		C4[i]=i*(i-1)*(i-2)*(i-3)/24;
		C3[i]=i*(i-1)*(i-2)/6;
	}
	scanf("%d",&k);
	for(cpgn=2;C4[cpgn+1]<=k&&cpgn<70;cpgn++) ;
	k-=C4[cpgn];
	dfs(k,0,cpgn);
	exit(1);
}

C++14(g++5.4) 解法, 执行用时: 210ms, 内存消耗: 133724K, 提交时间: 2018-08-10 18:25:24

#include <bits/stdc++.h>

int a[9999],b[9999],c4[99],c3[99],n,m,K,i,j,k,g,A;
short r[71][500001],f[71][500001];

int main(){
	c4[4]=1;
	for(i=5;i<71;i++)
		c4[i]=c4[i-1]*i/(i-4);
	c3[3]=1;
	for(i=4;i<71;i++)
		c3[i]=c3[i-1]*i/(i-3);
	r[2][0]=-1;
	for(i=3;i<71;i++)
		for(memcpy(r[i],r[i-1],sizeof r[i]),memcpy(f[i],f[i-1],sizeof f[i]),j=0;j<500001;j++)
			if(r[i][j]&&(k=j+c3[i])<500001&&(g=f[i][j]+1)<71&&(!r[i][k]||g<f[i][k]))
				r[i][k]=i,f[i][k]=g;
	scanf("%d",&K);
	for(A=70;A>3;A--)
		if((k=K-c4[A])>=0&&r[A][k]&&A+f[A][k]<76){
			for(n=A,i=2;i<=A;i++)
				for(j=1;j<i;j++)
					m++,a[m]=i,b[m]=j;
			while(k)
				for(n++,g=r[A][k],k-=c3[g],i=1;i<=g;i++)
					m++,a[m]=n,b[m]=i;
			printf("%d %d\n",n,m);
			while(m--)
				printf("%d %d\n",a[m+1],b[m+1]);
			break;
		}
	return 0;
}

上一题