利用graphviz來實現無向圖視覺化(求最短路徑)
阿新 • • 發佈:2018-12-14
1.首先下載graphviz,並安裝。
2.將輸入的邊儲存起來。
3.將最短路徑求出,並存儲每個頂點的前驅。
4.在程式中將建邊的程式碼寫入一個dot檔案中。
5.將dot檔案轉化為.png形式。
6.利用system函式開啟.png。
程式碼如下:
#include <cstdio> #include <cstring> #include <algorithm> #include <iostream> #include <stack> #include <vector> using namespace std; const int maxn = 1005; const int INF = 0x3f3f3f3f; int n, m; int head[maxn]; int pre[maxn][maxn]; int d[maxn][maxn]; int vis[maxn][maxn]; FILE* fp; struct edd { int x, y, len, id; }; struct edge { int to; int next; int len; }; edge e[maxn*maxn]; edd a[maxn*maxn]; //新增邊 void addedge(int x, int y, int len, int id) { e[id].to = y; e[id].len = len; e[id].next = head[x]; head[x] = id; } //單源最短路演算法 void djst(int S) { int vis[maxn]; memset(vis, 0, sizeof(vis)); for (int i = 1; i <= n; i++) { d[S][i] = INF; } d[S][S] = 0; while (1) { int Min = INF, u = -1; for (int i = 1; i <= n; i++) { if (!vis[i] && d[S][i] < Min) { Min = d[S][i]; u = i; } } if (u == -1) break; vis[u] = 1; for (int i = head[u]; i != -1; i = e[i].next) { int v = e[i].to; int len = e[i].len; if (!vis[v] && d[S][v] > d[S][u] + len) { d[S][v] = d[S][u] + len; pre[S][v] = u; } } } } //建立無向圖 void CreateGra() { memset(vis, 0, sizeof(vis)); memset(pre, -1, sizeof(pre)); memset(head, -1, sizeof(head)); fp = fopen("graph.dot", "w"); fprintf(fp, "%s", "graph g { \n"); printf("請輸入城市的個數及道路的總數: "); scanf("%d %d", &n, &m); printf("請依次輸入m條道路相連的兩個城市及長度: "); for (int i = 0, id = 0; i < m; i++) { int x, y, len; scanf("%d%d%d", &x, &y, &len); //fprintf(fp, "%d -- %d[label=%d];\n",x,y,len); a[i].x = x; a[i].y = y; a[i].len = len; a[i].id = i; addedge(x, y, len, id++); addedge(y, x, len, id++); } for (int i = 1; i <= n; i++) { djst(i); } } //尋找路徑 void Findpath(int x, int y) { vector<int>Road; int k = y; while (k != -1) { Road.push_back(k); fprintf(fp, "%d %s\n", k, "[style = \"filled\",color=\"blank\",fillcolor=\"chartreuse\"];"); k = pre[x][k]; } int Size = Road.size(); for (int j = Size - 1; j > 0; j--) { int len; for (int i = head[Road[j]]; i != -1; i = e[i].next) { if (e[i].to ==Road[j - 1]) { len = e[i].len; break; } } fprintf(fp, "%d -- %d[color=\"red\",label=%d];\n", Road[j], Road[j - 1], len); vis[Road[j]][Road[j - 1]] = 1; vis[Road[j - 1]][Road[j]] = 1; printf(" %d", Road[j]); } for (int i = 0; i < m; i++) { if (!vis[a[i].x][a[i].y]) { fprintf(fp, "%d -- %d[label=%d];\n", a[i].x, a[i].y, a[i].len); } } fprintf(fp, "}"); fclose(fp); } //查詢兩個頂點的最短路徑 void query() { printf("請輸入想要查詢的兩個頂點之間的最短路線:\n"); int m, n; Flag:scanf("%d%d", &m, &n); if (m == n) { printf("您輸入的是同一座城市,請重新輸入\n"); goto Flag; } else if (d[m][n] == INF) { printf("兩條道路之間沒有通路\n"); return; } else { Findpath(m, n); } system("dot -Tpng graph.dot -o Graph.png"); system("Start C:\\Users\\asus\\Desktop\\datastructvs\\findjst\\findjst\\findjst\\Graph.png"); } int main() { CreateGra(); query(); system("pause"); return 0; }
執行結果: