校园导游咨询

#include <iostream>
using namespace std;
#define MAXSIZE 100
#include<queue>
#include<stack>
/*dijkstra本质上的思想是贪心,它只适用于不含负权边的图.
我们把点分成两类,一类是已经确定最短路径的点,称为"白点",另一类是未确定最短路径的点,称为"蓝点"
dijkstra的流程如下::
1. 初始化dis[start] = 0,其余节点的dis值为无穷大.
2. 找一个dis值最小的蓝点x,把节点x变成白点.
3. 遍历x的所有出边(x,y,z),若dis[y] > dis[x] + z,则令dis[y] = dis[x] + z
4. 重复2,3两步,直到所有点都成为白点.
时间复杂度为O(n^2)*/
/*当所有边长都是非负数的时候,全局最小值不可能再被其他节点更新.所以在第2步中找出的蓝点x必然满足:dis[x]已经是起点到x的最短路径.
 我们不断选择全局最小值进行标记和拓展,最终可以得到起点到每个节点的最短路径的长度*/
typedef struct{
	string name;//景点名称;
	int id;//代号
	string Introduction;//简介
}ElemType;
typedef struct LNode
{
	ElemType data[MAXSIZE];
	int length;
}LNode,*List;
struct edge
{
	int to;//终点序号
	int w; //边的权值
	int next;//与该边同起点的上一条边的编号
};
struct node
{
	int w;
	int pos;
	bool operator <( const node &x )const
	{
		return x.w < w;
	}
};
priority_queue<node> q;
int f[MAXSIZE];
edge e[MAXSIZE];
int head[MAXSIZE];//head[i]表示以 i 为起点的最后一条边的编号
int dis[MAXSIZE];//dis[i]表示起点到i的最短路径的长度
int cnt;
bool vis[MAXSIZE];//表示该点是否被访问过

void Init(List &L)
{
	L=new LNode;
	L->length=0;
}
void Modify(List &L,int num,ElemType e)
{
	L->data[num]=e;
}
ElemType Search(List L,int num)
{
	return L->data[num];
}
inline void add_edge( int u, int v, int d )
{
	cnt++;
	e[cnt].w = d;
	e[cnt].to = v;
	e[cnt].next = head[u];
	head[u] = cnt;
}





inline void dijkstra(int s)
{
	dis[s] = 0;
	q.push( ( node ){0, s} );
	while( !q.empty() )
	{
		node tmp = q.top();
		q.pop();
		int x = tmp.pos, d = tmp.w;
		if( vis[x] )
			continue;
		vis[x] = 1;
		int y;
		for( int i = head[x]; i; i = e[i].next )
		{
			y= e[i].to;
			if( dis[y] > dis[x] + e[i].w )
			{
				dis[y] = dis[x] + e[i].w;
				if( !vis[y] )
				{
					q.push( ( node ){dis[y], y} );
					f[y]=x;
				}
			}
		}

	}
}




int main()
{

	cout<<"------------------------------"<<endl;
	cout<<"校园导游咨询"<<endl;
	cout<<"1、录入景点信息"<<endl;
	cout<<"2、修改景点信息"<<endl;
	cout<<"3、查询景点信息"<<endl;
	cout<<"4、查询2个景点间的最短路径和长度"<<endl;
	cout<<"5、退出"<<endl;
	cout<<"------------------------------"<<endl;
	List L;
	Init(L);
	while(true)
	{
		string a;
		cin>>a;
		if(a=="1")
		{
			cout<<"请输入景点数量、边的条数、景点信息、边的信息:"<<endl;
			int n,m;
			cin>>n>>m;
			for(int i=1;i<=n;i++)
			{
				cout<<"请输入第"<<i<<"个景点的信息"<<endl;
				cout<<"景点名称:";
				cin>>L->data[i].name;
				cout<<"代号:";
				cin>>L->data[i].id;
				cout<<"简介:";
				cin>>L->data[i].Introduction;
				L->length++;
				dis[i] = 0x7fffffff;
			}
			for(int i=1;i<=m;i++)
			{
				cout<<"请输入第"<<i<<"条边的起点、终点、长度:";
				int u,v,w;
				cin>>u>>v>>w;
				add_edge(u,v,w);
				add_edge(v,u,w);
			}
			cout<<"景点信息录入成功"<<endl;
		}
		else if(a=="2")
		{
			ElemType e;
			cout<<"请输入修改景点的代号:";
			int number;
			cin>>number;
			cout<<"请重新输入景点信息:"<<endl;
			cout<<"景点名称:";
			cin>>e.name;
			cout<<"代号:";
			cin>>e.id;
			cout<<"简介:";
			cin>>e.Introduction;
			Modify(L,number,e);
			cout<<"景点信息修改成功"<<endl;
		}
		else if(a=="3")
		{
			cout<<"请输入要查询景点的代号:";
			int number;
			cin>>number;
			ElemType e=Search(L,number);
			cout<<"景点名称:"<<e.name<<endl;
			cout<<"简介:"<<e.Introduction<<endl;
		}
		else if(a=="4")
		{
			cout<<"请输入2个景点的代号:";
			int start,end;
			cin>>start>>end;
			dijkstra(start);
			stack<int> s;
			int e=end;
			s.push(e);
			while (e!=start)
			{
				int tmp=f[e];
				s.push(tmp);
				e=tmp;
			}
			cout<<"景点"<<start<<"到景点"<<end<<"的一条最短路径为:"<<endl;
			while(!s.empty())
			{
				cout<<s.top()<<" ";
				s.pop();
			}
			cout<<endl;
			cout<<"最短路径的长度为:"<<dis[end]<<endl;
		}
		else{
			break;
		}
	}



}







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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值