1 非递归DFS
2 广搜
3 heap+dijkstra求单源最短路径
4 prim求最小生成树
5 拓扑序
注:如果求最小生成树需要记录那个点,只需要在pop的时候记录一下就好,不过在输入边的时候要统计边的号码(不统计也行,噶一下q数组,使其可以记录这个边的起点和末点就行)
同理,如果需要记录最短路的路径,只需要在pop的时候记录一下号码。
(或者输出这个号码qwq)
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define MAX_VERTEX_NUM 200 //顶点最大个数
const int maxn=400;
/*typedef struct ArcNode {int adjvex; struct ArcNode *nextarc; int weight; //边的尾巴。 int value;//边的权. }ArcNode; //表结点*/
#define VertexType int //顶点元素类型
typedef struct VNode
{int degree,indegree;//顶点的度,入度
//VertexType data;//点权
vector<pair<int,pair<int,int> > >g;
}VNode/*头结点*/,AdjList[MAX_VERTEX_NUM];
typedef struct{
AdjList vertices;
int vexnum,arcnum;//顶点的实际数,边的实际数
}ALGraph;
ALGraph G;
int d[maxn];
void add(int a,int b,int c)
{ G.vertices[a].g.push_back(make_pair(a,make_pair(b,c)));
G.vertices[a].degree++;
G.vertices[b].indegree++;
}
struct cmp
{bool operator()(pair<int,int> a,pair<int,int> b )
{ return a.first>b.first;//从大到小排序,但是小的权值大,所以先弹小的
//一句话,这和普通的排序是相反的。
}
};
void count_du()
{ for(int i=1;i<=G.vexnum;i++)
{ //cout<<G.vertices[i].indegree<<" "<<G.vertices[i].degree<<endl;
printf("%d的入度是:%d 出度是:%d\n",i,G.vertices[i].indegree,G.vertices[i].degree);
}
}
void MST(){
int s;
puts("请输出辣个源点");
scanf("%d",&s);
int d[maxn];
memset(d,0x3f,sizeof(d));
priority_queue<pair<int,int> ,vector<pair<int,int> >,cmp>q;
q.push(make_pair(s,0));
d[s]=0;
while(!q.empty()){
int u=q.top().first;
q.pop();
for(int i=0;i<G.vertices[u].g.size();i++){
pair<int,pair<int,int> > tt=G.vertices[u].g[i];
if(d[tt.second.first]>tt.second.second){
d[tt.second.first]=tt.second.second;
q.push(make_pair(tt.second.first,d[tt.second.first]));
}
}
}
long long all=0;
for(int i=1;i<=G.vexnum;i++){
{ printf("%d %d",i,d[i]);
all+=d[i];}
}
cout<<all<<endl;
}
void top_sort(){
queue<int>q;
queue<int>s;
bool vis[maxn];
for(int i=1;i<=G.vexnum;i++){
if(!G.vertices[i].indegree){//出度等于0
{q.push(i);
}
}
}
puts("拓扑排序序列为:");
bool flag=false;
while(!q.empty()){
int u=q.front();
q.pop();
s.push(u);
for(int i=0;i<G.vertices[u].g.size();i++){
int s=G.vertices[u].g[i].second.first;
G.vertices[s].indegree--;
if(!G.vertices[s].indegree)
{ flag=true;
q.push(s);
}
}
if(!flag)
{puts("有环!");break;}
}
if(flag){
while(!s.empty()){
printf("%d ",s.front());
s.pop();
}
printf("\n");
}
}
bool vis[maxn];
int DFS(int f){
stack<int>s;
s.push(f);
printf("%d ",f);
for(int i=0;i<G.vertices[f].g.size();i++){
if(!vis[G.vertices[f].g[i].second.first]){
s.push(G.vertices[f].g[i].second.first);
vis[G.vertices[f].g[i].second.first]=true;
}
while(!s.empty()){
int u=s.top();
s.pop();
vis[u]=true;
printf("%d ",u);
for(int j=0;j<G.vertices[u].g.size();j++){
if(!vis[G.vertices[u].g[j].second.first])
{ s.push(G.vertices[u].g[j].second.first);
vis[G.vertices[u].g[j].second.first]=true;
}
}
}
}
return 0;
}
int BFS(int s){
queue<int>q;
bool vv[maxn];
memset(d,0x3f,sizeof(d));
q.push(s);
d[s]=0;
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<G.vertices[u].g.size();i++){
int v=G.vertices[u].g[i].second.first;
if(!vv[G.vertices[u].g[i].second.first])
vv[G.vertices[u].g[i].second.first]=true;
q.push(v);
d[v]=d[u]+1;
}
}
for(int i=1;i<=G.vexnum;i++){
printf("%d 的层数为%d\n",i,d[i]);
}
}
int short_path(){
int s;
puts("请输出辣个源点");
scanf("%d",&s);
int d[maxn];
memset(d,0x3f,sizeof(d));
priority_queue<pair<int,int> ,vector<pair<int,int> >,cmp>q;
q.push(make_pair(s,0));
d[s]=0;
while(!q.empty()){
int u=q.top().first;
q.pop();
for(int i=0;i<G.vertices[u].g.size();i++){
pair<int,pair<int,int> > tt=G.vertices[u].g[i];
if(d[tt.second.first]>d[u]+tt.second.second){
d[tt.second.first]=d[u]+tt.second.second;
q.push(make_pair(tt.second.first,d[tt.second.first]));
}
}
}
for(int i=1;i<=G.vexnum;i++){
printf("%d距离到%d的距离为 %d\n",s,i,d[i]);
}
return 0;
}
int main()
{ int x,y,c;
cin>>G.vexnum>>G.arcnum;//点的数目和 边的数目
for(int i=1;i<=G.vexnum;i++)
{ G.vertices[i].degree=0;
G.vertices[i].indegree=0;
//G.vertices[i].firstarc->nextarc=NULL;
}
for(int i=0;i<G.arcnum;i++)
{ cin>>x>>y>>c;
add(x,y,c);
}
puts("前方高能!!下面分别实现下列功能:");
puts("1 输出各点的出度和入度,放心,会有汉字提示");
count_du();
puts("*****************************************");
puts("2 输出这个图的拓扑排序,如果有环我会告诉你的");
top_sort();
puts("******************************************");
puts("输出这个图的单源最短路径,源点请你告诉我,谢谢");
short_path();
puts("*****************************************");
memset(vis,false,sizeof(vis));
puts("实现深度优先非递归,我会输出给你dfs序,请告诉我初始点");
scanf("%d",&c);
d[c]=0;
vis[c]=true;
DFS(c);
puts("*****************************************");
puts("实现广度优先搜索,我会给你层数,请告诉我初始点");
scanf("%d",&c);
d[c]=0;
vis[c]=true;
BFS(c);
puts("******************************************");
puts("输出这个邻接表");
for(int i=1;i<=G.vexnum;i++){
printf("这个数字是%d ",i);
for(int j=0;j<G.vertices[i].g.size();j++){
printf("邻接的点%d 边权%d ",G.vertices[i].g[j].second.first,G.vertices[i].g[j].second.second);
}
cout<<endl;
}
puts("*****************************************");
MST();
puts("*****************************************");
return 0;
}