Beautiful Graph CodeForces - 1093D 二分图判定 简单组合
Beautiful Graph CodeForces - 1093D 二分图判定 简单组合
题意
给定一张\(n\)个点\(m\)条边的无向图,可以给每个点赋值\(1,2,3\)。
要求赋值以后每条边的两个端点权值和是奇数,问有多少种赋值方法,答案对\(998244353\)取模
\[1\leq t \leq 3 \times 10^5\\
1\leq n \leq 3 \times 10^5,0\leq m\leq3 \times 10^5
\]
分析
显然只有2不能和1或3组合才可以,于是可以发现把原图抽象成2分图,然后对两个分部统计个数即可。
不同的连通块可以通过乘法原理算答案。每个连通块内一部可以填1也可以填3,也可以左边2或者右边2
于是每一块的答案就是\(2^p + 2^q\)
如果连通块不是二分图,那么无法做到
代码
vector<int> e[maxn];
ll pow2[maxn];
int col[maxn];
int c1,c2;
bool flag;
void dfs(int u,int co){
col[u] = co;
if(!co) c1++;
else c2++;
for(auto v:e[u]){
if(col[v] < 0) dfs(v,co ^ 1);
else if(col[v] == co){
flag = false;
return;
}
}
}
void solve(){
int n = readint();
int m = readint();
flag = true;
for(int i = 0;i <= n;i++) e[i].clear(),col[i] = -1;
for(int i = 0;i < m;i++){
int x = readint();
int y = readint();
e[x].pb(y);
e[y].pb(x);
}
ll ans = 1;
for(int i = 1;i <= n;i++){
if(col[i] == -1){
c1 = c2 = 0;
dfs(i,0);
if(!flag) {
ans = 0;
break;
}
ans *= pow2[c1] + pow2[c2];
ans %= MOD;
}
}
cout << ans << '\n';
}
int main(){
int T = readint();
pow2[0] = 1ll;
for(int i = 1;i < maxn;i++)
pow2[i] = (pow2[i - 1] << 1) % MOD;
while(T--){
solve();
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步