[agc011C]Squared Graph-[二分图]

Description

传送门

Solution

我们以下考虑的情况都是原图中非孤立的点。

题目要求新图的连通块个数。这个不好算,我们考虑计算新图的联通块内的特征点(x,y),即无法通过移动找到(t,c)使得t<x,也无法找到点(x,a)满足a<y。(就是字典序最小吧)可知每个新图连通块内,都有且只会有1个特征点。这两者就等价。

对于新图的点(x,y),假如x,y所在原图连通块已确定,则第一纬度的x一定要是其所在原图联通块的最小编号点。第二维度y的话,如果y所在原图连通块是二分图,则y在被二分出来的两个点集中分别选择最小的点,都是满足要求的。(否则的话,第二维度y只能选其所在连通块内的最小编号点)

直接统计即可。(孤立点的计数。。em这个就比较好推,我就不赘述啦)

Code

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
const int M=2e5+10,N=1e5+10;
int n,m,x,y;
struct pas{int y,nxt;
}g[M<<1];int h[N],tot;
bool vis[N];int f[N];
int t1,t2,t3;
void cover(int x)
{
    vis[x]=1;
    for (int i=h[x];i;i=g[i].nxt) if (!vis[g[i].y]) cover(g[i].y);
}
bool dfs(int x)
{
    vis[x]=1;
    bool ret=1;
    int i;
    for (i=h[x];i;i=g[i].nxt)
    if (!vis[g[i].y]){ f[g[i].y]=f[x]^1;if (!dfs(g[i].y)) {ret=0;break;}}
    else if (f[g[i].y]==f[x]) {ret=0;break;}
    for (;i;i=g[i].nxt) cover(g[i].y);  
    return ret;
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d",&x,&y);
        g[++tot]=pas{y,h[x]};h[x]=tot;
        g[++tot]=pas{x,h[y]};h[y]=tot;
    }
    for (int i=1;i<=n;i++) 
    {
        if (!h[i]) t1++;
        else if (!vis[i]) if (dfs(i)) t2++;else t3++;
    }
    ll ans;
    ans=1ll*t1*t1+2ll*t1*(n-t1)+2ll*t2*t2+2ll*t2*t3+1ll*t3*t3;
     
    printf("%lld",ans);
}

 

转载于:https://www.cnblogs.com/coco-night/p/9733256.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值