代码如下:
#include <cstdio>
#include <cmath>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define CLR(a,b) memset(a,b,sizeof(a))
#define INF 0x3f3f3f3f
#define LL long long
#define MAXSIZE 100
bool vis[MAXSIZE+5];
int in[MAXSIZE+11]; //入度
int f[MAXSIZE+11]; //并查集指向根节点
typedef struct
{
int x,y;
int cost;
}road[(MAXSIZE*MAXSIZE+MAXSIZE)>>1],Road;
typedef struct //邻接矩阵
{
int arcs[MAXSIZE+5][MAXSIZE+5];
int vexnum,arcnum;
void init()
{
CLR(this->arcs,0);
this->arcnum = this->vexnum = 0;
}
}AMGraph;
typedef struct ArcNode //邻接表,顶点序号用数字表示
{
int adjvex;
struct ArcNode *nextarc;
}AdjList[MAXSIZE+5],AdjNode;
typedef struct
{
AdjList vectices;
int vexnum,arcnum; //顶点、边数
void init() //初始化
{
for (int i = 1 ; i <= MAXSIZE ; i++)
this->vectices[i].nextarc = NULL;
this->arcnum = this->vexnum = 0;
}
void Insert(int pos,AdjNode &t) //在pos点后连接t节点
{
t.nextarc = this->vectices[pos].nextarc;
this->vectices[pos].nextarc = &t;
}
}ALGraph;
typedef struct Queue //队列
{
int data;
struct Queue *next;
struct Queue *end; //队列末节点
void init()
{
this->end = this;
this->next = NULL;
}
int GetTop()
{
return this->next->data;
}
bool Empty()
{
if (this->next == NULL)
return true;
return false;
}
void Pop()
{
Queue *t = this->next;
this->next = this->next->next;
free(t);
if (this->Empty()) //如果队列为空,队尾指针指向自己
this->end = this;
}
void Push(int x)
{
Queue *t;
t = (Queue *)malloc(sizeof(Queue));
t->data = x;
t->next = NULL;
this->end->next = t;
this->end = t;
}
}Queue;
void dfsSearch(AMGraph &mm,int pos) //递归求DFS
{
printf ("%d ",pos);
vis[pos] = true;
for (int i = 1 ; i <= mm.vexnum ; i++)
{
if (!vis[i] && mm.arcs[pos][i])
dfsSearch(mm,i);
}
}
void DFS(AMGraph &mm)
{
printf ("该无向图的DFS序为:");
dfsSearch(mm,1);
puts("");
}
void BFS(AMGraph &mm)
{
printf ("该无向图的BFS序为:");
CLR(vis,false);
Queue q;
q.init();
q.Push(1);
vis[1] = true;
while (!q.Empty())
{
int pr = q.GetTop();
q.Pop();
printf ("%d ",pr);
for (int i = 1 ; i <= mm.vexnum ; i++)
{
if (!vis[i] && mm.arcs[pr][i]) //没有遍历过,并且存在边
{
q.Push(i);
vis[i] = true;
}
}
}
printf ("\n");
}
void dijkstra(AMGraph &mm)
{
CLR(vis,false);
int dis[MAXSIZE+5];
CLR(dis,INF);
dis[1] = 0;
while (1)
{
int v = -1;
for (int i = 1 ; i <= mm.vexnum ; i++)
{
if (!vis[i] && (v == -1 || dis[i] < dis[v]))
v = i;
}
if (v == -1)
break;
vis[v] = true; //标记
for (int i = 1 ; i <= mm.vexnum ; i++)
{
if (vis[i] == false && mm.arcs[v][i])
dis[i] = min(dis[i] , dis[v] + mm.arcs[v][i]);
}
}
printf ("%d\n",dis[mm.vexnum] == INF ? -1 : dis[mm.vexnum]); //不存在最短路径输入-1
}
void ShortestRoad(AMGraph &mm)
{
printf ("从1点到%d点的最短路径为(不存在输出-1):",mm.vexnum);
dijkstra(mm);
}
int find(int x) //递归寻根节点并路径压缩
{
if (x != f[x])
f[x] = find(f[x]);
return f[x];
}
bool join(int x,int y) //合并节点
{
int fx,fy;
fx = find(x);
fy = find(y);
if (fx != fy)
{
f[fx] = fy;
return true;
}
return false;
}
bool cmp(Road a,Road b)
{
return a.cost < b.cost;
}
void Kruskal(AMGraph &mm)
{
for (int i = 1 ; i <= mm.vexnum ; i++)
f[i] = i; //初始化并查集根节点
int ant = 0;
road d;
for (int i = 1 ; i < mm.vexnum ; i++)
{
for (int j = i + 1 ; j <= mm.vexnum ; j++)
{
if (mm.arcs[i][j])
{
d[ant].x = i;
d[ant].y = j;
d[ant++].cost = mm.arcs[i][j];
}
}
}
sort(d,d+ant,cmp);
int cost = 0; //最小花费
for (int i = 0 ; i < ant ; i++)
{
if (join(d[i].x , d[i].y))
cost += d[i].cost;
}
printf ("%d\n",cost);
}
void MiniSpanTree(AMGraph &mm)
{
printf ("最小生成树的最小花费为:");
Kruskal(mm);
}
void Topo(ALGraph &am)
{
printf ("拓扑排序结果为:");
Queue q;
q.init();
for (int i = 1 ; i <= am.vexnum ; i++)
{
if (!in[i])
q.Push(i);
}
while (!q.Empty())
{
int pr = q.GetTop();
printf ("%d ",pr);
q.Pop();
in[pr] = -1;
AdjNode *t;
t = am.vectices[pr].nextarc;
while (t != NULL)
{
in[t->adjvex]--;
if (!in[t->adjvex])
q.Push(t->adjvex);
t = t->nextarc;
}
}
puts("");
}
int main()
{
int arcnum,vexnum;
AMGraph mm; //Matrix map
ALGraph am; //Adj map
mm.init() , am.init();
printf ("请输入顶点数的边数:");
scanf ("%d %d",&vexnum,&arcnum);
am.arcnum = mm.arcnum = arcnum;
am.vexnum = mm.vexnum = vexnum;
printf ("请输入%d条边(DFS、BFS、最短路、最小生成树中存为无向图 ; 拓扑排序用有向图):\n",arcnum);
for (int i = 1 ; i <= arcnum ; i++) //读入数据
{
int x,y,z; //顶点,边的权值
scanf ("%d %d %d",&x,&y,&z);
mm.arcs[x][y] = mm.arcs[y][x] = z;
AdjNode t;
t.adjvex = y;
t.nextarc = NULL;
in[y]++;
am.Insert(x,t); //插入邻接表中
}
DFS(mm);
BFS(mm);
ShortestRoad(mm);
MiniSpanTree(mm);
Topo(am);
return 0;
}
/*
1 3 1
3 7 1
7 6 1
6 3 1
1 2 1
2 5 1
5 8 1
8 4 1
4 2 1
*/