图(无向图代码)

/* 测试数据
5 7
1 2 12
1 4 18
1 3 16
2 3 2
3 4 4
5 2 22
4 5 10


*/
#include <iostream>
#include <cstring>
#include <queue>
#include<algorithm>
using namespace std;
typedef int VertexType;
const int maxSize = 50;
bool vis[maxSize];
int n, e;       //n个村e条边

int f[maxSize];
int distances[maxSize];
int distant[maxSize][maxSize];
const int INF = 0x3f3f3f;
int path[maxSize];  //存储点到点需要经过哪些点
int fpath[maxSize][maxSize];
int *lowcost;
int *vset;

//定义邻接矩阵
typedef struct MGraph
{
    int edges[maxSize][maxSize];
    int n, e;
    VertexType vex[maxSize];
}MGraph;


//定义邻接表
typedef struct ArcNode
{
    int adjvex;
    struct ArcNode *nextarc;
    double info;
}ArcNode;
typedef struct VNode
{
    int data;
    ArcNode *firstarc;
}VNode;
typedef struct AGraph
{
    VNode adjlist[maxSize];
    int n, e;
}AGraph;

void DFSMGraph(MGraph adjacent, int v)    //邻接矩阵DFS
{
    cout << v << " ";
    vis[v] = 1;
    for(int i = 1; i <= n; i++)
    {
        if(vis[i] == 0 && adjacent.edges[v][i] != 0)
            DFSMGraph(adjacent, i);
    }
}

void DFSAGraph(AGraph adjacency, int v)    //邻接表DFS
{
     ArcNode *p;
     vis[v] = 1;
     cout << v << " ";
     p = adjacency.adjlist[v].firstarc;
     while (p != NULL)
     {
        if(vis[p->adjvex] == 0)
        DFSAGraph(adjacency, p->adjvex);
        p = p->nextarc;
     }
}

void BFSMGraph(MGraph adjacent, int v)		//邻接矩阵BFS
{
    queue<int> q;
    q.push(v);
    cout << v << " ";
    vis[v] = 1;
    while(!q.empty())
    {
    	int temp = q.front();
    	q.pop();
    	for(int i = 1 ; i <= n ; i++)
    	{
    		if(adjacent.edges[temp][i] != 0 && vis[i] == 0)
    		{
    			cout << i << " ";
    			vis[i] = 1;
    			q.push(i);
			}
		}
	}

}

void BFSAGraph(AGraph adjacency, int v)//邻接表BFS
{
	queue<int> q;
	ArcNode *p;
	cout << v << " ";
	vis[v] = 1;
	p = adjacency.adjlist[v].firstarc;
	while(!q.empty())
	{
		int front = q.front();
		q.pop();
		while(p != NULL)
		{
			if(vis[p->adjvex] == 0)
			{
				cout << p->adjvex << " ";
				vis[p->adjvex] = 1;
				q.push(p->adjvex);
			}
			p = p->nextarc;
		}
	}

}

void dfsIsTree(MGraph adjacent, int v, int &count, int &side)
{
	vis[v] = 1;
	count ++;
	for(int i = 1; i <= n; i++)
	{
		if(vis[i] == 0 && adjacent.edges[v][i] != 0)
		{
			vis[i] = 1;
			side++;
			dfsIsTree(adjacent, i, count, side);
		}
	}
}
bool GisTree(MGraph adjacent)
{
	int count = 0, side = 0;
	memset(vis, 0, sizeof(vis));
	dfsIsTree(adjacent, 1, count, side);
	if(count == n && side == n-1)
		return true;
	else
	return false;
}


typedef struct Road
{
	int a, b;
	int distance;
}Road;
int getfather(int v)
{
	return v == f[v] ? v:getfather(f[v]);
}
bool cmp(Road a, Road b)
{
	return a.distance < b.distance;
}
void unions(int x, int y)
{
	x = getfather(x);
	y = getfather(y);
	if(x != y)
		f[x] = y;
}
void Kruskal(int distances[], Road road[])
{
	int j = 0;
	for(int i = 1; i <= e; i++)
	{
		int a = getfather(road[i].a);
		int b = getfather(road[i].b);
		if(a != b)
		{
			unions(a, b);
			distances[++j] = road[i].distance;
		}
	}
	distances[0] = j;
	for(int i = 1; i <= n; i++)
		f[i] = getfather(f[i]);
}

void Prim(MGraph adjacent, int *lowcost, int *vset, int v0)
{
	int k;
	lowcost[v0] = 0;
	vset[0] = n;
	lowcost[0] = n;
	for(int i = 1; i <= vset[0]; i++)
	{
		vset[i] = 0;
		lowcost[i] = adjacent.edges[v0][i] ;
	}
	vset[v0] = 1;
	for(int i = 1; i <= n; i++)
	{
		int min = INF;
		for(int j = 1; j <= n; j++)
		{
			if(vset[j] == 0 && lowcost[j] < min)
			{
				k = j;
				min = lowcost[j];
			}
		}
		vset[k] = 1;
		for(int j = 1; j <= n; j++)
		{
			if(vset[j] == 0 && adjacent.edges[k][j] < lowcost[j])
			lowcost[j] = adjacent.edges[k][j];
		}
	}
}


void printfPath(int path[], int a)  //逆序输出路径
{
    int stack1[maxSize], top = -1;
    while(path[a] != -1)
    {
        stack1[++top] = a;
        a = path[a];
    }
    stack1[++top] = a;
    while( top != -1)
    {
        if(top == 0)
            cout << stack1[top--]  ;
        else
            cout << stack1[top--] << " -> ";
    }

}

void Dijkstra(MGraph g, int v, int dist[], int path[])	//邻接表的 Dijsktra
{
    for(int i = 1; i <= g.n; i++)
    {
        dist[i] = g.edges[v][i];
        if( g.edges [v][i] < INF )
            path[i] = v;
        else
            path[i] = -1;
    }
    vis[v] = 1;
    path[v] = -1;

    for(int i = 1; i <= g.n; i++)
    {
        int min1 = INF;
        int k = -1; //  用来标记找到最小值
        for(int j = 1; j <= g.n; j++)
        {
            if( !vis[j] && min1 > dist[j])
            {
                min1 = dist[j];
                k = j;
            }
        }
        vis[k] = 1;
        for(int j = 1; j <= g.n; j++)
            if( vis[j] == 0 && dist[j] > dist[k] + g.edges[k][j] )
            {
                path[j] = k;
                dist[j] = dist[k] + g.edges[k][j];
            }
    }

    for(int i = 1; i <= g.n; i++)
    {
        if(dist[i] == INF)
        {
            cout << v << " 到 " << i << " 没有通路 " << endl;
            continue;
        }
        cout << "从顶点 " << v << " 到顶点 " << i << "的最短路径为:" ;
         printfPath(path, i);
     	cout << "	 路径长度为:" << dist[i] << endl;
    }

}

void AGDijkstra(AGraph m, int v, int dist[], int path[])	//邻接表的Dijkstra
{
	ArcNode *p;
	p = m.adjlist[v].firstarc;
	vis[v] = 1;
	for(int i = 1; i <= m.n; i++)
	{
		dist[i] = INF;
		path[i] = -1;
	}
	dist[v] = 0;
	path[v] = -1;
	int k = -1, min1 = INF;
	while( p )
	{
		dist[p->adjvex] = p->info;
		if( !vis[p->adjvex] && min1 > p->info)
		{
			min1 = p->info;
			k = p->adjvex;
			path[p->adjvex] = v;
		}
		p = p->nextarc;
	}

	while(1){
		k = -1, min1 = INF;
		for(int j = 1; j <= m.n; j++)
        {
            if( !vis[j] && min1 > dist[j])
            {
                min1 = dist[j];
                k = j;
            }
        }
		if(k == -1) break;
		vis[k] = 1;
		p = m.adjlist[k].firstarc;
		while ( p ){
			if( !vis[p->adjvex] && dist[p->adjvex] > dist[k] + p->info )
			{
				path[p->adjvex] = k;
				dist[p->adjvex] = dist[k] + p->info;
			}
			p = p->nextarc;
		}
	}
    for(int i = 1; i <= m.n; i++)
    {
        if(dist[i] == INF)
        {
            cout << v << " 到 " << i << " 没有通路 " << endl;
            continue;
        }
        cout << "从顶点 " << v << " 到顶点 " << i << "的最短路径为:" ;
         printfPath(path, i);
     	cout << "	 路径长度为:" << dist[i] << endl;
    }

}


void printfPath(int path[][maxSize], int u, int v)
{
	if(path[u][v] == -1)
	{
		cout << v << " ";
	}
	else
	{
		int mid = path[u][v];
		printfPath(path, u, mid);
		printfPath(path, mid, v);
	}
}

void Floyd(MGraph g, int dist[][maxSize], int path[][maxSize]){
	for(int i = 1; i <= g.n; i++)
		for(int j = 1; j <= g.n; j++){
			dist[i][j] = g.edges[i][j];
			path[i][j] = -1;
		}

	for(int i = 1; i <= g.n; i++)
		for(int j = 1; j <= g.n; j++)
			for(int k = 1; k <= g.n; k++){
				if(dist[i][j] > dist[i][k] + dist[k][j]){
					dist[i][j] = dist[i][k] + dist[k][j];
					path[i][j] = k;
				}
			}
	cout << "请输入你要找的两个城市:" << endl;
	int u, v;
	cin >> u >> v;
	if(dist[u][v] == INF)
    {
        cout << u << " 到 " << v << " 没有通路 " << endl;
    }
	cout << "路径为:" << u << " ";
	printfPath(path, u, v);
	cout << "路径长度为:" << dist[u][v] << endl;
}

int main()
{
    MGraph adjacent;        //邻接矩阵
    AGraph adjacency;       //临街表

    int x, y;       //x村y村
    double z;       //x村y村 距离为z
	Road road[maxSize];
    //以下为邻接矩阵存图
    cout << "请输入几个村庄,几条边(无向图,村庄数从1开始编号):" << endl;
    cin >> n >> e;
    adjacent.e = e;
    adjacent.n = n;
    for(int i = 1; i <= n; i++)
    {
        adjacent.vex[i] = i;
    }

    //以下为邻接表存图
    adjacency.e = e;
    adjacency.n = n;
    for(int i = 1; i <= n; i++)
    {
        adjacency.adjlist[i].data = i;
        adjacency.adjlist[i].firstarc = NULL;
    }

    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
        {
        	if(i == j)
        	adjacent.edges[i][j] = 0;
        	else
            adjacent.edges[i][j] = INF;
        }
    cout << "请输入村庄和村庄,村庄之间的路径:" << endl;
    for(int i = 1; i <= e; i++)
    {
        cin >> x >> y >> z;
        road[i].a = x;
        road[i].b = y;
        road[i].distance = z;
        //以下为邻接矩阵存图
        if(adjacent.edges[x][y] > z)
        {
        	adjacent.edges[x][y] = z;
       		adjacent.edges[y][x] = z;
		}


        //以下为邻接表存图
        ArcNode *p = new ArcNode;
        p->adjvex = y;
        p->nextarc = adjacency.adjlist[x].firstarc;
        p->info = z;
        adjacency.adjlist[x].firstarc = p;
        p = new ArcNode;
        p->adjvex = x;
        p->nextarc = adjacency.adjlist[y].firstarc;
        p->info = z;
        adjacency.adjlist[y].firstarc = p;
    }

        cout << "邻接矩阵DFS :" << endl;
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; i++)
        if(vis[i] == 0)
            DFSMGraph(adjacent, i);

	cout << endl;

    cout << "邻接表DFS :" << endl;
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; i++)
        if(vis[i] == 0)
            DFSAGraph(adjacency, i);

    cout << endl;

	cout << "邻接矩阵BFS :" << endl;
    memset(vis, 0, sizeof(vis));
    for(int i = 1; i <= n; i++)
    	if(vis[i] == 0)
        BFSMGraph(adjacent, i);
	cout << endl;

	cout << "邻接表BFS :" << endl;
	 memset(vis, 0, sizeof(vis));
	 for(int i = 1; i <= n; i++)
	 {
	 	if(vis[i] == 0)
	 	BFSAGraph(adjacency, i);
	 }
	 cout << endl;

	 if(GisTree(adjacent))
	 	cout << "这个图是树" << endl;
	 else
	 	cout << "这个图不是树" << endl;


	sort(road+1,road+n+1,cmp);
	for(int i = 1 ;i <= n ;i++)
	{
		f[i] = i;
		distances[i] = INF;
	}
	int sum = 0;
	int count = 0;
	if(e < n-1)
	{
		cout << "无法用kruskal,生成最小生成树,因为边太少" << endl;
	 }
	else
	{
		Kruskal(distances, road);
		for(int i = 1; i <= n ; i++)
		{
			if( f[i] == i)
			count ++;
		}

		if(count == 1)
		{
			for(int i = 1; i <= distances[0]; i++)
			sum += distances[i];
			cout << "Kruskal算法最小生成树的值为 = " << sum << endl;
		}
		else
		{
			cout << "无法用kruskal,生成最小生成树,因为不是连通图" << endl;
		}
	}


	sum = 0;
	count = 0;
	lowcost = new int[n + 1];
	vset = new int[n + 1];
	if(e < n-1)
	{
		cout << "无法用Prim,生成最小生成树,因为边太少" << endl;
	}
	else
	{
		Prim(adjacent,lowcost, vset, 1);
		for(int i = 1; i <= n ; i++)
		{
			if(lowcost[i] == INF)
			count++;
		}
		if(!count)
		{
			for(int i = 1; i <= lowcost[0]; i++)
			sum += lowcost[i];
			cout << "Prime算法最小生成树的值为 = " << sum << endl;
		}
		else
		{
			cout << "无法用Prim,生成最小生成树,因为不是连通图" << endl;
		}
	}


    memset(vis, 0, sizeof(vis));
    int v;
    cout << "请输入你想要找单元最短路径的顶点:" << endl;
    cin >> v;
    if( v > adjacent.n )
    {
        cout << "没有这么多村庄,村庄数目为: " << adjacent.n << " 请重新输入:"<< endl;
        cin >> v;
    }
    if( v == 0 )
    {
        cout << "村庄编号从1开始,村庄数目为: " << adjacent.n << " 请重新输入:"<< endl;
        cin >> v;
    }
    Dijkstra(adjacent, v, distances, path);	//	邻接矩阵
    //AGDijkstra(adjacency, v, distances, path);	//邻接表


    Floyd(adjacent, distant, fpath);


	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值