agc011c Squared Graph

给出一个 \(n\) 个点, \(m\) 条边的无向图。从这个图生成一个新的图,\((a,b)\)\((a',b')\) 之间存在一条边如果 \(a\)\(b\) 之间在原图有一条边, \(a'\)\(b'\) 之间在原图有一条边。求新图有多少个连通块。

\(2\leq n\leq 10^5, 0\leq m\leq 2\times10^5\)

图中不存在自环。

首先画成一个 \(n\times n\) 的图,这就是最终的图。

如果要求新图有多少个连通块,那么考虑是否和老图的连通块有关。

先考虑简单的三个点的图,假设这三个点都联通,有两种情况

存在边 \((1,2), (2,3)\),画一画,发现新图存在两个连通块

存在边 \((1,2), (2,3), (1,3)\), 画一画,发现新图只有一个连通块

此时有一个猜想,是不是树就存在一个连通块,但是如果有环就有两个连通块

接着继续画,如果是四个点呢

存在边 \((1,2),(2,3),(3,4)\),发现新图存在两个联通快,和我的猜想一样

存在边 \((1,2),(2,3),(3,4),(1,4)\),发现新图存在两个连通块,gg! 这个和之前的猜想不一样!

存在边 \((1,2),(2,3),(1,3),(3,4)\),发现新图存在一个连通块

存在边 \((1,2),(2,3),(3,4),(1,4),(1,3),(2,4)\),发现新图存在一个连通块

根据进一步的画图,发现猜想出现了一个问题,但是可以确定新图连通块只存在 \(1\) 个或者 \(2\) 个连通块。

那么怎么分辨是一个还是两个呢?其实根据奇环和偶环有一个idea,是不是跟二分染色有关,如果可以二分染色,就是2,如果不可以就是1。

如何证明呢?

考虑将原图二分染色,如果原图可以二分染色,发现新图的边存在两种情况 \((0,0)\)\((1,1)\)\((0,1)\)\((1,0)\),那么 \((0,0)\) 的边永远连不到 \((0,1)\) ,就会存在 \(2\) 个连通块,相反就只有 \(1\) 个。

剩下的就一个问题,如果是两个连通块之间连边呢,同样,如果两个连通块都可以二分染色,就是 \(2\) 个连通块,否则新连起来的连通块就是 \(1\) 个连通块。

只需要统计一下可以二分染色的连通块个数,不可以的个数,以及只有一个点的连通块个数,然后计算一下就好了。

真的是一个非常巧妙的题目,可惜我一开始画图一直都没画对 Q^Q,早知道写个代码求连通块个数就好了。

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

空间复杂度: \(O(n+m)\)

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=1e5+10;
int n,m;
vector<int>g[N]; 
int col[N],cnt=0,odd=0,even=0,one=0;
void dfs(int x,int c,bool &bi){
	cnt++;
	col[x]=c;
	for(auto to:g[x]){
		if(col[to]==-1){
			dfs(to,c^1,bi);
		}else if(col[to]!=c^1)bi=false;
	}
}
int main(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int u,v;
		scanf("%d%d",&u,&v);
		g[u].push_back(v);
		g[v].push_back(u);
	}
	for(int i=1;i<=n;i++)col[i]=-1;
	for(int i=1;i<=n;i++){
		if(col[i]==-1){
			bool bi=true;
			cnt=0;
			dfs(i,0,bi);
			if(cnt!=1){
				if(bi)even++;
				else odd++;	
			}else one++;
		}
	}
//	cerr<<"one="<<one<<" odd="<<odd<<" even="<<even<<endl;
	ll ans=0;
	ans+=1ll*n*one*2-1ll*one*one;
//	cerr<<1ll*n*one*2-1ll*one*one<<endl;
	ans+=1ll*even*odd*2+1ll*odd*odd;
	ans+=1ll*even*even*2;
	printf("%lld\n",ans); 
	return 0;
}
posted @ 2026-04-03 03:28  xyangh  阅读(14)  评论(0)    收藏  举报