AT2339-[AGC011C]Squared Graph【黑白染色】

1|0正题

题目链接:https://www.luogu.com.cn/problem/AT2339


1|1题目大意

给出n个点m条边的一张无向图,然后有一张n×n的图,每个点是一个二元组(a,b)(a,b)(c,d)连边当且仅当ac有连边,bd有连边。

求新图的连通块数量

1n105,1m2×105


1|2解题思路

计数问题,我们考虑固定一个基准,以原图中的连通块为基准。

对于一个点(x,y),它能走到的点,发现如果xy所在的连通块都可以黑白染色,那么xy的黑白顺序是固定的,否则无论如何x整个都可以变为整个连通块或者y可以变为整个连通块。

然后这样一些会发现样例都过不了,因为有一种很特殊的点,就是没有任何边连接的点,这一部分的点我们需要特判。

记大小不是1的连通块数为A,其中能奇偶染色的为B,大小为1的连通块数为C,那么答案就是:

A×A+B×B+C×n×2C×C

时间复杂度:O(n+m)


1|3code

#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2e5+10; struct node{ ll to,next; }a[N<<1]; ll n,m,tot,siz,A,B,C,ls[N],v[N]; bool flag; void addl(ll x,ll y){ a[++tot].to=y; a[tot].next=ls[x]; ls[x]=tot;return; } void dfs(ll x,ll c){ if(v[x]==(c^1))flag=1; if(v[x]>=0)return;v[x]=c;siz++; for(ll i=ls[x];i;i=a[i].next) dfs(a[i].to,c^1); return; } signed main() { scanf("%lld%lld",&n,&m); for(ll i=1,x,y;i<=m;i++){ scanf("%lld%lld",&x,&y); addl(x,y);addl(y,x); } memset(v,-1,sizeof(v)); for(ll i=1;i<=n;i++) if(v[i]<0){ flag=siz=0;dfs(i,0); if(siz==1)C++; else A++,B+=!flag; } printf("%lld\n",1ll*A*A+1ll*B*B+2ll*C*n-C*C); return 0; }

__EOF__

本文作者QuantAsk
本文链接https://www.cnblogs.com/QuantAsk/p/15978172.html
关于博主:退役OIer,GD划水选手
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   QuantAsk  阅读(46)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示