P10378 [GESP202403 七级] 交流问题题解
思路
我们把关系想成一张图,每次输入就给两个人连一条边。
因为一个人只有两种选择,所以我们在一个联通块内随便找一个点,跑一遍搜索,找出这个联通块内的答案。代码如下。
void dfs(int u,int color) { cnt2++;// cnt2是这个连通块内的总点数 cnt1+=color;//这个是一所学校内的人 vis[u]=1; //因为一个人不是A校就是 B校,所以对整张图进行染色 //所以一个点u假如是白色,与他相连的所有点就是黑色 for(auto v:edge[u]) { if(!vis[v]) { dfs(v,color^1); /* 相当于 if(color==1) dfs(v,0) else dfs(v,1) */ } } } //统计答案 //因为一个人最多即为 max(cnr2-cnt1,cnt1)
主函数内只需要一个变量统计一下所有联通快的总和就行了。
讲一个有趣的性质,符合要求的图不可能包含偶环,它只能是由树和奇环组成的图,如基环树。证明我就不写了,大家可以画个图试试。
代码
最后附上代码。
#include <bits/stdc++.h> using namespace std; vector<int> edge[100010]; int ans, vis[100010], cnt1, cnt2; void dfs(int u, int color) { cnt2++; cnt1 += color; vis[u] = 1; for (auto v : edge[u]) { if (!vis[v]) { dfs(v, color ^ 1); } } } int main() { int n, m; cin >> n >> m; for (int i = 1; i <= m; i++) { int u, v; cin >> u >> v; edge[u].push_back(v); edge[v].push_back(u); } for (int i = 1; i <= n; i++) { if (!vis[i]) { cnt1 = cnt2 = 0; dfs(i, 0); ans += max(cnt2 - cnt1, cnt1); } } cout << min(ans, n - ans) << " " << max(ans, n - ans); return 0; }
本文作者:merlinkkk
本文链接:https://www.cnblogs.com/merlinkkk/p/18306123
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步