2022年多校冲刺NOIP联训测试3 T3 团(clique)

本题解来自于洛谷大佬@_HMZ_

大概题意:给一张无向图,将这张图分为两个点集,每个点集构成的图是一个完全图(即团),使得两张完全图的边总数最小。

我们知道,一张完全图的边数是 $\frac{n\times(n-1)}{2}$。 假设第一个点集的点数是 $n$,第二个点集的点数是 $m$, 边数就是 $\frac{n\times(n-1)}{2} + \frac{m\times(m-1)}{2}$。

除 $2$ 可以忽略,所以变成 $n\times(n-1) + m\times(m-1)$。

根据分配律,$n^2 - n + m^2 -m$。 而我们又知道,$n+m$ 为定值。

所以我们只需要让 $n^2 + m^2$ 最小就好了。

这里 $n$ 和 $m$ 越接近,答案就越小,感性理解一下,不做证明。

这里还有一个 trick,我们先建出补图,对于一些点,如果它们在补图上互相不连通,那么这些点就是一张完全图。

这个其实很显然。

那么,我们就可以先建出补图,然后,对于一个连通块分别处理。

这个连通块中,如果 $i$ 和 $j$ 有边,那么 $i$ 和 $j$ 必定属于不同的点集(根据上面的结论)。 由于点集只有两个,所以这就变成了二分图染色,如果给出的图不是二分图,就可以输出无解。

那么如何使得 $n$ 和 $m$ 更接近?

我们已知二分图染色只有两种情况(即黑色变成白色,白色变成黑色)。

所以我们可以跑一遍 dp,来求出答案。

#include<iostream>
using namespace std;
int n,m,tot,head[1000005],col[1000005],fir,sec,val[1000005],c;
bool dp[2005],vis[2005][2005],f[2005];
int ans=1e9;
struct node
{
    int y,nex;
}s[8000005];
void add(int i,int j)
{
    s[++tot].y=j,s[tot].nex=head[i];
    head[i]=tot;
}
void dfs(int now,int c)
{
    col[now]=c;
    if(c==1)    ++fir;
    else    ++sec;
    for(int i=head[now];i;i=s[i].nex)
    {
        int y=s[i].y;
        if(col[y] && col[y]==c)
        {
            cout<<-1;
            exit(0);
        }
        else if(!col[y])
            dfs(y,3-c);
    }
}
signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    cin>>n>>m;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++)
        {
            char u;
            cin>>u;
            vis[i][j]=u-'0',vis[i][j]=!vis[i][j];
            if(vis[i][j] && i!=j)   add(i,j);
        }
    dp[0]=true;
    for(int i=1;i<=n;i++)
    {
        if(!col[i])
        {
            fir=0,sec=0;
            dfs(i,1);
            for(int j=0;j<=n;j++)
                f[j]=dp[j],dp[j]=0;
            for(int j=0;j<=n;j++)
            {
                if(j>=fir)  dp[j]|=f[j-fir];
                if(j>=sec)  dp[j]|=f[j-sec];
            }
        }
    }
    for(int i=0;i<=n;i++)
    {
        if(dp[i])
        {
            int fir=i,sec=n-i;
            ans=min(ans,fir*(fir-1)/2+sec*(sec-1)/2);
        }
    }
    cout<<ans;
    return 0;
}

 

posted @ 2022-07-21 16:28  Day_Dreamer_D  阅读(78)  评论(0)    收藏  举报