图的邻接表存储,大数乘法注意事项,二分图染色,AcWing 4415. 点的赋值
1、在图的邻接表存储中,可以使用模拟链表法:
const int N,M=2*N;
h[N],e[M],ne[M],idx;//链表头/链表结点的序号/链表节点的下一个节点
void add(int a,int b)
{
e[idx]=b;
ne[idx]=h[a];
h[a]=idx++;
}
也可以使用unordered_map<int,vector<int>> 或 vector<vector<int>>记录;
在可以的情况下,尽量使用vector而非unordered_map,vector要比unordered_map快很多,后者可能会超时。
2、在结果比较大的情况下,最好每一步都进行%MOD操作,防止数据超出范围。如例题中,做pow2的每一步都要%MOD。
3、二分图可以用染色法进行判断和计数。color数组存储颜色0、1、2,然后dfs进行判断,如果存在颜色冲突,则返回false,否则继续dfs。
例题 AcWing 4415. 点的赋值

#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N=300010; const int M=N*2; const LL MOD =998244353; LL pow2(LL num) { LL base=1; while(num--) { base*=2; base%=MOD; } return base; } bool dfs(int i,int c,LL &s1,LL &s2,vector<vector<int>> &node_adj,vector<int> &color) { color[i]=c; if(c==1) { s1++; } else { s2++; } for(auto j:node_adj[i]) { if(color[j]&&color[j]!=3-c) { return false; } else { if(!color[j]&&!dfs(j,3-c,s1,s2,node_adj,color)) { return false; } } } return true; } void YD() { int n, m; cin >> n >> m; vector<vector<int>> node_adj(n+1); for (int i = 0; i < m; i++) { int n1, n2; cin >> n1 >> n2; node_adj[n1].push_back(n2); node_adj[n2].push_back(n1); } LL res = 1; vector<int> color(n + 1, 0); for (int i = 1; i <= n; i++) { if (!color[i]) { LL s1=0,s2=0; if(dfs(i,1,s1,s2,node_adj,color)) { res*=(LL(pow2(s1)+pow2(s2))%MOD); res*=1; res%=MOD; } else { res=0; break; } } } cout << res << endl; } int main() { int T; cin >> T; while (T--) { YD(); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人