1. 程式人生 > >利用graphviz來實現無向圖視覺化(求最短路徑)

利用graphviz來實現無向圖視覺化(求最短路徑)

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;
}

 執行結果: