
补图+染色二分图判奇环+vcc(结论:vcc若存在奇环,则整个vcc都包含在奇环内
预处理定义:包括常用宏定义和初始化代码 补图构建:对原始图构建补图以处理双连接分量 Tarjan 算法:用于进行深度优先搜索,检测强连通分量 深度优先搜索 (DFS):用于标记图中的双连通分量 图遍历及其应用:通过DFS确定图的双连通分量并进行标记
发布日期:2021-05-16 17:22:38
浏览次数:18
分类:精选文章
本文共 3215 字,大约阅读时间需要 10 分钟。
#include#include #include using namespace std;#define mem(a, b) memset(a, b, sizeof(a))#define INF 0x3F3F3F3F#define DNF 0x7F#define DBG printf("Debug: %s\n", __FILE__)typedef struct { int to; int next; int weight;} Edge;void add_edge(int f, int t) { edge_cnt++; edge[edge_cnt].to = t; edge[edge_cnt].next = head[f]; head[f] = edge_cnt++;}// 补图表示bool graph[1005][1005];vector< vector > vcc;int dfn[1005], low[1005], times = 0, top = 0, type = 0;int mark[1005], color[1005], ans[1005], ok = 0;void tarjan(int u) { dfn[u] = low[u] = times++; stack.push(u); for (int v = head[u]; v; v = edge[v].next) { if (!dfn[v]) { tarjan(v); low[u] = min(low[u], low[v]); if (low[v] > dfn[u]) { type++; while (!stack.empty() && stack.top() != v) { stack.pop(); vcc[type].push_back(stack.top()); } vcc[type].push_back(u); } } else { low[u] = min(low[u], dfn[v]); } } stack.pop();}void dfs(int u) { if (ok) return; for (int v = head[u]; v; v = edge[v].next) { if (mark[v]) { if (color[v] == 0) { color[v] = -color[u]; dfs(v); } else { if (color[v] == color[u]) { ok = 1; return; } } } }}void init() { graph = {false}; mem(dfn, 0); mem(low, 0); mem(stack, 0); head = {-1}; ans = {0};}int main() { #define LOCAL freopen("data.in", "r", stdin); freopen("odata.out", "w", stdout); while (scanf("%d %d", &n, &m) != EOF) { if (n == 0 && m == 0) break; init(); graph = {false}; for (int i = 1; i <= m; i++) { int u, v; scanf("%d %d", &u, &v); graph[u][v] = graph[v][u] = true; } // 构建补图 for (int i = 1; i <= n; i++) { for (int j = i + 1; j <= n; j++) { if (!graph[i][j]) { add_edge(i, j); add_edge(j, i); } } } for (int u = 1; u <= n; u++) { if (!dfn[u]) { tarjan(u); } } for (int i = 1; i <= type; i++) { ok = 0; for (auto v : vcc[i]) { mark[v] = 1; } color[vcc[i][0]] = 1; dfs(vcc[i][0]); if (ok) { for (auto v : vcc[i]) { ans[v] = 1; } } for (auto v : vcc[i]) { mark[v] = 0; color[v] = 0; } } int total = count(ans); cout << total << endl; }}
上述代码实现了图的双连接分量识别算法,主要包括以下几个部分:
代码中主要使用了以下技术:
- Depth-First Search (DFS)
- Tarjan 算法
- 图的双连通分量识别
- 补图构建
代码的主要功能是对输入图中的顶点进行双连通分量识别,可以应用于网络攻击 анализ、病毒传播分析等场景。
发表评论
最新留言
表示我来过!
[***.240.166.169]2025年05月01日 05时06分03秒
关于作者

喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!
推荐文章
libvirtd:内部错误:Failed to apply firewall rule
2019-03-13
优先级队列2
2019-03-13
TiKV 源码解析系列文章(十三)MVCC 数据读取
2019-03-13
Android 开发常用的工具类(更新ing)
2019-03-13
EasyUI的简单介绍
2019-03-13
初次安装webpack之后,提示安装webpack-cli
2019-03-13
Hbase压力测试
2019-03-14
C#中的类、方法和属性
2019-03-14
Python爬虫训练:爬取酷燃网视频数据
2019-03-14
Python数据分析入门(十九):绘制散点图
2019-03-14
Callable中call方法和Runnable中run方法的区别
2019-03-14
Linux yum提示Loaded plugins错误的解决方法
2019-03-14
Netty的体系结构及使用
2019-03-14
xshell解决文本粘贴格式错误
2019-03-14
网络+图片加载框架(英文版)
2019-03-14
JAVA BigInteger和BigDecimal类常用方式
2019-03-14
深度学习框架 各种模型下载集合 -- models list
2019-03-14
机器学习全教程
2019-03-14