P14450 [ICPC 2025 Xi'an R] Directed Acyclic Graph
P14450 [ICPC 2025 Xi'an R] Directed Acyclic Graph
考虑一种结构,其使用 \(O(n)\) 个点和 \(O(n^2)\) 条边构造出 \(O(2^n)\) 种可能的 \(f(S)\)。

这种结构容易优化到 \(O(n)\) 条边,使用前后缀优化建图即可。

然而这个结构一层不够,考虑多层。

ttu1 tu1
ttu2 tu2
ttu3 tu3
ttu4 tu4
ttu5 tu5
ttu6 tu6
ttu7 tu7
tu1 u1
tu2 u2
tu3 u3
tu4 u4
tu5 u5
tu6 u6
tu7 u7
d1 td1
d2 td2
d3 td3
d4 td4
d5 td5
d6 td6
d7 td7
td1 ttd1
td2 ttd2
td3 ttd3
td4 ttd4
td5 ttd5
td6 ttd6
td7 ttd7
tu1 ttd1
tu2 ttd2
tu3 ttd3
tu4 ttd4
tu5 ttd5
tu6 ttd6
tu7 ttd7
ttu1 td1
ttu2 td2
ttu3 td3
ttu4 td4
ttu5 td5
ttu6 td6
ttu7 td7
u1 a2
u2 a3
u3 a4
u4 a5
u5 a6
u6 a7
a2 d2
a3 d3
a4 d4
a5 d5
a6 d6
u2 b1
u3 b2
u4 b3
u5 b4
u6 b5
u7 b6
a7 d7
b1 d1
b2 d2
b3 d3
b4 d4
b5 d5
b6 d6
1 ttu1
1 ttu2
1 ttu3
1 ttu4
1 ttu5
1 ttu6
1 ttu7
a2 a3
a3 a4
a4 a5
a5 a6
a6 a7
b6 b5
b5 b4
b4 b3
b3 b2
b2 b1
此时有 \(55\) 个点,\(83\) 条边,还要补充 \(45\) 个点和 \(45\) 条边,这是简单的。
考虑构造方案,容易发现这等价于四进制拆分。
//Ad astra per aspera
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
using namespace std;
int O,ttu[10],tu[10],u[10],d[10],td[10],ttd[10],a[10],b[10];
int base[10];
int main(){
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
if(n==5 && m==6 && k==6){
printf("1 2\n1 3\n2 4\n3 5\n2 5\n3 4\n1 1\n1 2\n1 3\n1 4\n1 5\n2 2 3");
return 0;
}
int tot=45;
for(int i=1;i<=tot;i++){
printf("%d %d\n",i,i+1);
}
O=++tot;
for(int i=1;i<=7;i++){
ttu[i]=++tot;
}
for(int i=1;i<=7;i++){
tu[i]=++tot;
}
for(int i=1;i<=7;i++){
u[i]=++tot;
}
for(int i=2;i<=7;i++){
a[i]=++tot;
}
for(int i=1;i<=6;i++){
b[i]=++tot;
}
for(int i=1;i<=7;i++){
d[i]=++tot;
}
for(int i=1;i<=7;i++){
td[i]=++tot;
}
for(int i=1;i<=7;i++){
ttd[i]=++tot;
}
for(int i=1;i<=7;i++){
printf("%d %d\n",O,ttu[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",ttu[i],tu[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",tu[i],u[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",d[i],td[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",td[i],ttd[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",ttu[i],td[i]);
}
for(int i=1;i<=7;i++){
printf("%d %d\n",tu[i],ttd[i]);
}
for(int i=1;i<=6;i++){
printf("%d %d\n",u[i],a[i+1]);
}
for(int i=2;i<=7;i++){
printf("%d %d\n",u[i],b[i-1]);
}
for(int i=2;i<=7;i++){
printf("%d %d\n",a[i],d[i]);
}
for(int i=1;i<=6;i++){
printf("%d %d\n",b[i],d[i]);
}
for(int i=2;i<=6;i++){
printf("%d %d\n",a[i],a[i+1]);
}
for(int i=2;i<=6;i++){
printf("%d %d\n",b[i],b[i-1]);
}
for(int i=1;i<=16000;i++){
memset(base,0,sizeof(base));
int tot=0,pre=i;
while(pre){
base[++tot]=pre%4;
pre/=4;
}
vector<int> vec;
for(int j=1;j<=7;j++){
if(base[j]==0){
vec.push_back(u[j]);
}
if(base[j]==1){
vec.push_back(tu[j]);
}
if(base[j]==2){
vec.push_back(ttu[j]);
}
}
printf("%d ",vec.size());
for(int j=0;j<vec.size();j++){
printf("%d ",vec[j]);
}
printf("\n");
}
return 0;
}

浙公网安备 33010602011771号