计蒜客 16958 Colored Graph(构造)

本文探讨了在一个无向完全图中如何通过黑白染色边来最小化同色三元环的数量,并提供了一种有效的方法及实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Description

给出一个nn个点的无向完全图,要求给每条边黑白染色,使得图中同色三元环的数量最少,输出最少数量以及染色矩阵

Input

第一行一整数T表示用例组数,每组用例输入一整数nn表示点数(n500)

Output

输出最少同色三元环数,然后输出一个n×nn×n的染色矩阵AijAijAij=1Aij=1表示i,ji,j两点之间的边染黑色,Aij=2Aij=2表示i,ji,j两点之间的边染白色

Sample Input

2
3
6

Sample Output

0
0 1 1
1 0 2
1 2 0
2
0 2 2 1 1 1
2 0 2 1 1 1
2 2 0 1 1 1
1 1 1 0 2 2
1 1 1 2 0 2
1 1 1 2 2 0

Solution

a[i]a[i]为第ii个点连出去的白色边数量,那么第i个点连出去的黑色边数量即为n1a[i]n−1−a[i],对于一个不同色三元环,必然是两条边一个颜色另一条边另一个颜色,也即有一个点连出去的两条边是同色的,另外两个点连出去的两条边是异色的,考虑每个点对于不同色三元环的贡献可以得到该图同色三元环个数为C3n12i=1na[i](n1a[i])Cn3−12∑i=1na[i]⋅(n−1−a[i]),为使该值最小,我们要让每一个a[i](n1a[i])a[i]⋅(n−1−a[i])最大,也即a[i]=n12a[i]=n−12,考虑构造使得每个点连出去的白色边数量为n12n−12,每次把所有点剩余的白边数量排序,从数量最小的点开始往数量最大的点连边直至数量最小的点的白边连完即可,此时最少同色三元环数量即为C3nnn12(n1n12)2Cn3−n⋅n−12⋅(n−1−n−12)2

Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>
#include<ctime>
using namespace std;
typedef long long ll;
typedef pair<int,int>P;
const int INF=0x3f3f3f3f,maxn=505;
P a[maxn];
int g[maxn][maxn];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                g[i][j]=(i==j?0:1);
        for(int i=1;i<=n;i++)a[i].first=(n-1)/2,a[i].second=i;
        for(int i=1;i<=n;i++)
        {
            sort(a+i,a+n+1);
            int j=n;
            while(a[i].first&&j>i)
            {
                g[a[i].second][a[j].second]=g[a[j].second][a[i].second]=2;
                a[i].first--;
                a[j].first--;
                j--;
            }
        }
        int ans=n*(n-1)*(n-2)/6-n*((n-1)/2)*(n-1-(n-1)/2)/2;
        printf("%d\n",ans);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                printf("%d%c",g[i][j],j==n?'\n':' ');
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值