图(Dijkstra,Prim,Kruskal)

图的一些算法包括:

1 遍历算法

        DFS 一条路走到底不行再回 (堆栈)

        BFS 把窝边草吃完在吃外面一圈(队列实现)

2 生成树算法

        Kruskal 每次总找最小边,且最小边不是在已经弄完的集合

        Prim 先找一个点然后根据这个顶点每次搜索外面的顶点到已经形成集合最小边

3 最短路径

        Dijkstra(俩个顶点)有边数为负数不能用得用下面那个

        Floyd(多源)

#include<iostream>
#include<sstream>
#include<queue>
#include<vector>
#include<algorithm>
using namespace std;
#define MAX 10
#define MAXVAL   9999
class K
{
public:
	int i, j;
	int  data;
	bool operator<(K b)
	{
		return data < b.data;
	}
};
template<class  T>
class  MGraph {
	T   vertex[MAX];//顶点
	int  edge[MAX][MAX];//邻接矩阵
	int  vertexNum, edgeNum;//定点数和边数
public:
	MGraph(T  a[], int n, int  e);//有向图
	MGraph(T  a[], int n, int  e,int m);
	void ouput();
	void BFS();
	void Prim();//生成树
	void Kruskal();//极小连通子图
	int find(int a[], int x);//并查集
	void DisBFS(int v);//所有顶点到v的最短路径  不带权值
	void Dijkstra1(int v);//最短路径  带权值
	void Dijkstra(int v,int x);
	void Floyd();//多源最短路

};
template<class  T>
MGraph<T>::MGraph(T  a[], int n, int  e)
{
	vertexNum = n; edgeNum = e;//din
	int  i, j, k, weight;
	for (i = 0; i < n; i++)//存储顶点
		vertex[i] = a[i];
	for (i = 0; i < MAX; i++)//初始化邻接矩阵
		for (j = 0; j < MAX; j++)
			if (i == j)edge[i][j] = 0;
			else  edge[i][j] = MAXVAL;

	cout << "\n input  " << edgeNum << "  zu  shu  ju  (i,j weight) \n";
	for (k = 1; k <= e; k++) //输入边
	{
		cin >> i >> j >> weight;//输入边的顶点,权
		edge[i][j] = weight;
		//edge[j][i] = weight;
	}

}
template<class T>
MGraph<T>::MGraph(T  a[], int n, int  e,int m)
{
	vertexNum = n; edgeNum = e;//din
	int  i, j, k, weight;
	for (i = 0; i < n; i++)//存储顶点
		vertex[i] = a[i];
	for (i = 0; i < MAX; i++)//初始化邻接矩阵
		for (j = 0; j < MAX; j++)
			if (i == j)edge[i][j] = 0;
			else  edge[i][j] = MAXVAL;

	cout << "\n input  " << edgeNum << "  zu  shu  ju  (i,j weight) \n";
	for (k = 1; k <= e; k++) //输入边
	{
		cin >> i >> j >> weight;//输入边的顶点,权
		edge[i][j] = weight;
		edge[j][i] = weight;
	}

}
template<class T>
void MGraph<T>::ouput()
{
	cout << "\t";
	for (int i = 0; i < vertexNum; i++)
	{
		cout << vertex[i] << "\t";
	}cout << endl;
	for (int i = 0; i < vertexNum; i++)
	{
		cout << vertex[i] << "\t";
		for (int o = 0; o < vertexNum; o++)
		{
			if (edge[i][o] != MAXVAL)cout << edge[i][o] << "\t";
			else cout << "?\t";
		}cout << endl;
	}
}
template<class T>
void MGraph<T>::BFS()
{
	static bool flag[MAX] = { 0 };
	queue<int> q;
	q.push(0);
	flag[0] = 1;
	while (!q.empty())
	{
		for(int i=0;i<vertexNum;i++)
		if (edge[q.front()][i] != MAXVAL && edge[q.front()][i] != 0)
			if (!flag[i]) {
				q.push(i);
				flag[i] = 1;
			}
		cout << q.front() << " ";
		q.pop();
	}
}
template<class T>
void MGraph<T>::Prim()
{
	int adjvex[MAX] = { 0 }, lowcost[MAX] = { 0 };
	for (int i = 0; i < vertexNum; i++)
	{
		lowcost[i] = edge[0][i];
	}
	for (int k = 1; k < vertexNum; k++)
	{
		int min=-1;
		for (int j = 0; j < vertexNum; j++)
		{
			if (lowcost[j] != 0 && min == -1) min = j;
			else if (lowcost[j] != 0 && lowcost[min] > lowcost[j]) min = j;
		}	
		cout << "(" << vertex[min] << "," << vertex[adjvex[min]] << ")" << "权值是" << lowcost[min] << endl;
		lowcost[min] = 0;
		for (int j = 0; j < vertexNum; j++)
		{
			if (lowcost[j] > edge[j][min])
			{
				lowcost[j] = edge[min][j];
				adjvex[j] = min;
			}
		}
	}
	for (int i = 0; i < vertexNum; i++)
		cout << i << " " <<adjvex[i]  << endl;
}
template<class T>
void MGraph<T>::Kruskal()
{
	int a[MAX];
	K b[MAX * MAX];
	int t = 0;
	for (int i = 0; i < vertexNum; i++)
		a[i] = i;
	for (int i = 0; i < vertexNum; i++)
	{
		for (int j = 0; j < vertexNum; j++)
		{
			if (edge[i][j] != 0 && edge[i][j] != MAXVAL)
			{
				b[t].i = i;
				b[t].j = j;
				b[t].data = edge[i][j];
				t++;
			}
		}
	}
	sort(b, b + t);
	for (int i = 0; i < t; i++)
	{
		int x = find(a, b[i].i);
		int y = find(a, b[i].j);
		if (x != y)
		{
			cout <<vertex[ b[i].i] << ", " << vertex[b[i].j] << "权值为" << edge[b[i].i][b[i].j] << endl;
			a[x] = y;
		}
		else continue;
		//cout << b[i].i << " " << b[i].j << " " << b[i].data << endl;
	}

}
template<class T>
int MGraph<T>::find(int a[], int x)
{
	if (a[x] != x) 
		return find(a, a[x]);
	return x;
}
template<class T>
void MGraph<T>::DisBFS(int v)
{
	int dis[MAX] = { 0 };
	queue<int> q;
	q.push(v);
	dis[v] = 0;
	while (!q.empty())
	{
		for(int i=0;i<vertexNum;i++)
			if (edge[i][q.front()] != 0 && edge[i][q.front()] != MAXVAL&&dis[i]==0&&i!=v)
			{
				q.push(i);
				dis[i] = dis[q.front()] + 1;
				cout << i << "到 " << 0 << "的最短路径" << dis[i] << endl;
			}
		q.pop();
	}
}
template<class T>
void MGraph<T>::Dijkstra1(int v)//自己根据广度搜索瞎写的不一定对
{
	int dis[MAX],flag[MAX] = { 0 };
	for (int i = 0; i < vertexNum; i++)
		dis[i] = edge[v][i];
	queue<int> q;
	q.push(v);
	flag[v] = 1;
	while (!q.empty())
	{
		for (int i = 0; i < vertexNum; i++)
			if (edge[i][q.front()] != 0 && edge[i][q.front()] != MAXVAL  && i != v)
			{
				if (!flag[i])
				{
					q.push(i);
					flag[i] = 1;	
				}		
				dis[i] =min(dis[i], dis[q.front()] + edge[q.front()][i]);
			}
		q.pop();
	}
	for (int i = 0; i < vertexNum; i++)
	{
		cout << v << "到" << i << "最短路径为" << dis[i] << endl;
	}
}
template<class T>
void MGraph<T>::Dijkstra(int v,int x)//也不是标准的算法,弄不明白和别人不一样
{
	string path[MAX];
	int dis[MAX], k = v;
	for (int i = 0; i < vertexNum; i++)
	{
		dis[i] = edge[v][i];
		path[i] = vertex[v] ;
	}
	while (k != x)
	{	
		dis[k] = 0;	
	    k = v;	
		for (int o = 0; o < vertexNum; o++)
			if (dis[o] != 0 && ((k == v) || (dis[o] < dis[k])))k = o;
		cout << v << "到" << k << "最短路径为" << dis[k] << endl;
		for (int o = 0; o < vertexNum; o++)
			if (dis[o] > dis[k] + edge[k][o])
			{
				dis[o] = dis[k] + edge[k][o];
				path[o] += vertex[k];
			}		
	}
	//cout << v << "到" << x << "最短路径为" << dis[x] << endl;
	cout << path[x] << vertex[x] << endl;

}
template<class T>
void MGraph<T>::Floyd()
{
	int  D[MAX][MAX];
	for (int i = 0; i < vertexNum; i++)
		for (int o = 0; o < vertexNum; o++)
			D[i][o] = edge[i][o];
	for (int i = 0; i < vertexNum; i++)
		for (int o = 0; o < vertexNum; o++)
			for (int j = 0; j < vertexNum; j++)
				D[o][j] = min(D[o][j],D[o][i] + D[i][j]) ;
				
	for (int i = 0; i < vertexNum; i++)
	{
		for (int o = 0; o < vertexNum; o++)
			cout<<D[i][o]<<" ";
		cout << endl;
	}
}
int main()
{
	int n, m;
	string a[10];
	cin >> n >> m;
	for (int i = 0; i < n; i++)
		a[i] = " V"+to_string(i);
		//a[i] = ('a' + i);
	MGraph<string> M(a, n, m,0);
	//M.BFS();
	M.ouput();
	/*cout << endl;
	M.Prim();
	cout << endl;
	M.Kruskal();*/
	//M.DisBFS(0);

	M.Dijkstra(0,2);
	M.Dijkstra1(0);
	M.Floyd();
	return 0;
}



/*
 6 9
 0 1 34 
 0 2 46 
 0 5 19 
 2 5 25  
 2 3 17 
 3 5 25 
 3 4 38 
 5 4 26 
 1 4 12 
*/
/*
5 7
0 1 10
0 3 30
0 4 100
1 2 50
2 4 10
2 3 20
3 4 60

7 10
0 4 11
0 6 7
1 2 8
3 1 10
3 5 3
4 3 7
5 4 10
5 2 9
6 1 15
6 3 6
*/

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DyingLive

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值