Graphviz 是个好东西,可以画树和图之类的东西。本文记了一些常用的属性以及自动生成 Dot 代码的邻接表模板。
摘录一些常用的属性,完整 ref:
graph
代表无向图,digraph
是有向图rankdir
可以设置成LR
来支持从左到右的布局,即 DAG 的风格shape
可以设置节点形状,具体参见多边形节点label
可以设置边上的权值
下面是自动生成 Dot 代码的邻接表模板:
template<typename T, size_t n, size_t m>
struct Graph {
struct { int to, nxt; T w; } v[m];
int h[n], cnt;
Graph() { memset(h, -1, sizeof(h)); }
void add(int x, int y, const T& w) { v[cnt] = {y, h[x], w}; h[x] = cnt++; }
void out(const char* filename, bool directed, bool weighted) {
FILE* f = fopen(filename, "w");
fprintf(f, "%s main{\n", directed ? "digraph" : "graph");
FO(i, 0, n - 1) {
FE(j, *(this), i) {
if (j % 2 == 0 && !directed) continue;
fprintf(f, "\t%d%s%d", v[j].to, directed ? "->" : "--", i);
if (weighted)
fprintf(f, "[label=\"%s\"]\n", std::to_string(v[j].w).c_str());
}
if (~h[i]) fprintf(f, "%d[shape=circle]", i);
}
fputs("}", f);
fclose(f);
}
};
filename
,directed
,weighted
三个参数分别表示输出文件名,是否为有向图,是否为带权图- 无向图的加边必须连续
- 用到了
std::to_string
,所以需要在 C++1y 下编译 - 需要配合板子集合里的总模板食用
- 默认圆形比较美观
- 生成后通过命令行编译即可:
dot -Tpng <input> -o <output>
然鹅,我发现了一个更牛逼的生成器,Graph_Editor